c# NameValueCollection 不同的值
c# NameValueCollection distinct values
C#代码如下:
NameValueCollection nvc = new NameValueCollection();
nvc.Add("color", "red");
nvc.Add("size", "s");
nvc.Add("color", "red");
nvc.Add("size", "m");
nvc.Add("color", "red");
nvc.Add("size", "l");
//blue
nvc.Add("color", "blue");
nvc.Add("size", "m");
nvc.Add("color", "blue");
nvc.Add("size", "l");
//green
nvc.Add("color", "green");
nvc.Add("size", "s");
nvc.Add("color", "green");
nvc.Add("size", "m");
nvc.Add("color", "green");
nvc.Add("size", "l");
实际结果:
color:red,red,red,blue,blue,green,green,green
size:s,m,l,m,l,s,m,l
希望结果:
color:red,blue,green
size:s,m,l
给你的一些想法:
NameValueCollection
允许重复值。使用 Dictionary<string, string>
.
NameValueCollection
是一个较旧的对象,仅强类型化为 string, string
。 Dictionary
更灵活,因为你可以指定类型参数。
当使用 Dictionary
时请注意,如果您尝试添加相同的密钥两次,您将收到错误消息。这可以通过稍微更改语法来解决。而不是 Add()
,只需使用索引器:
var myDict = new Dictionary<string, string>();
myDict["color"] = "blue";
myDict["color"] = "blue"; // no harm doing this twice
根据我的经验,在所有地方使用字符串是一种让 bug 蔓延的方法,并且很容易出错(嗯,想知道我是怎么知道的?)。很容易拼错某些东西,或者为颜色指定尺寸,反之亦然。
有什么理由不能在代码中强类型化概念吗?
public abstract class ProductAttribute { }
public sealed class Color : ProductAttribute {
private Color(string value) { Value = value; }
public Value { get; }
public static readonly Blue = new Color("blue");
public static readonly Green = new Color("green");
private static readonly IReadOnlyDictionary<string, Color> _colorDict =
new ReadOnlyDictionary<string, Color>(
new List<Color> {
Blue, Green
}.ToDictionary(color => color.Value, color => color)
);
public static Color GetColor(string value) {
Color color;
_colorDict.TryGetValue(value, out color);
return color;
}
}
然后对尺寸做类似的事情。这只是一个想法,可能不是很灵活(您必须更改代码以添加新值),但它应该向您展示什么是可能的。
但看看你现在能做什么:
var attrs = new HashSet<ProductAttribute>;
attrs.Add(Color.Blue);
attrs.Add(Color.Green);
attrs.Add(Color.Blue); // no problem
attrs.Add(Color.GetColor("blue")); // no problem
attrs.Add(Size.Small);
attrs.Add(Size.Medium);
attrs.Add(Size.Medium); // no problem
使用 ProductAttribute
classes 的一种方法如下:
foreach (ProductAttribute attr in attrs) {
Color color = attr as Color;
if (color != null) {
// work with color
}
}
或者,您可以创建一个 ProductAttributeType
枚举,将其作为参数添加到 ProductAttribute
构造函数中,并在 ProductAttribute
中以只读摘要 属性 公开它=] class。然后你所有的 subclasses 都传递它们是什么类型,你可以很容易地得到正在做的事情的类型 attr.ProductAttributeType == ProductAttributeType.Color
例如。
我不确定您的用例,NameValueCollection
允许重复项更好地用于此类情况 Dictionary
。
您仍然可以在 NameValueCollection
上执行类似的操作以获得您想要的结果。
var results = nvc.AllKeys
.GroupBy(g=>g)
.Select(s=>
new
{
key = s.Key,
values = nvc.GetValues(s.Key).Distinct()
});
foreach(var result in results)
{
Console.WriteLine("{0}- {1}", result.key, string.Join(",", result.values) ;
}
工作Example
老问题,但我需要类似的东西(在 VB.Net 中,但在 C# 中很容易应用);我正在使用该集合编译 words/word 组和值之间的引用,同时忽略大小写。字典解决方案会覆盖值,只维护最后一个值,并且绑定到列表的字典变得比我喜欢的更麻烦。为了准确了解所要求的内容,我首先使用以下语法添加:
If Not nvc.AllKeys.Contains(name) OrElse Not nvc.GetValues(name).Contains(value) Then nvc.Add(name, value)
大量重复调用相同的键和值不会非常有效,但这可能是我能找到的最简单的方法。这最终变得多余,并且在我的代号中(有时甚至是值)是临时构建的;为了尽可能减少 code/variables 并提高效率(仍然使用这种效率低下的方法),我首先考虑构建一个 Sub 而是创建了这个:
Private Class NoDupValueNameValueCollection
Inherits Collections.Specialized.NameValueCollection
Public Overrides Sub Add(name As String, value As String)
If Not MyBase.AllKeys.Contains(name) OrElse Not MyBase.GetValues(name).Contains(value) Then MyBase.Add(name, value)
End Sub
End Class
或 C#
private class NoDupValueNameValueCollection : System.Collections.Specialized.NameValueCollection {
public override void Add(string name, string value) {
if (!(base.AllKeys.Contains(name)) || !(base.GetValues(name).Contains(value))) base.Add(name, value);
}
}
它现在可以代替 nvc 使用,并且与 nvc 完全一样,并且可以防止重复值。事实上,这正是所要求的:防止添加重复值的 NameValueCollection
C#代码如下:
NameValueCollection nvc = new NameValueCollection();
nvc.Add("color", "red");
nvc.Add("size", "s");
nvc.Add("color", "red");
nvc.Add("size", "m");
nvc.Add("color", "red");
nvc.Add("size", "l");
//blue
nvc.Add("color", "blue");
nvc.Add("size", "m");
nvc.Add("color", "blue");
nvc.Add("size", "l");
//green
nvc.Add("color", "green");
nvc.Add("size", "s");
nvc.Add("color", "green");
nvc.Add("size", "m");
nvc.Add("color", "green");
nvc.Add("size", "l");
实际结果:
color:red,red,red,blue,blue,green,green,green
size:s,m,l,m,l,s,m,l
希望结果:
color:red,blue,green
size:s,m,l
给你的一些想法:
NameValueCollection
允许重复值。使用Dictionary<string, string>
.NameValueCollection
是一个较旧的对象,仅强类型化为string, string
。Dictionary
更灵活,因为你可以指定类型参数。当使用
Dictionary
时请注意,如果您尝试添加相同的密钥两次,您将收到错误消息。这可以通过稍微更改语法来解决。而不是Add()
,只需使用索引器:var myDict = new Dictionary<string, string>(); myDict["color"] = "blue"; myDict["color"] = "blue"; // no harm doing this twice
根据我的经验,在所有地方使用字符串是一种让 bug 蔓延的方法,并且很容易出错(嗯,想知道我是怎么知道的?)。很容易拼错某些东西,或者为颜色指定尺寸,反之亦然。
有什么理由不能在代码中强类型化概念吗?
public abstract class ProductAttribute { }
public sealed class Color : ProductAttribute {
private Color(string value) { Value = value; }
public Value { get; }
public static readonly Blue = new Color("blue");
public static readonly Green = new Color("green");
private static readonly IReadOnlyDictionary<string, Color> _colorDict =
new ReadOnlyDictionary<string, Color>(
new List<Color> {
Blue, Green
}.ToDictionary(color => color.Value, color => color)
);
public static Color GetColor(string value) {
Color color;
_colorDict.TryGetValue(value, out color);
return color;
}
}
然后对尺寸做类似的事情。这只是一个想法,可能不是很灵活(您必须更改代码以添加新值),但它应该向您展示什么是可能的。
但看看你现在能做什么:
var attrs = new HashSet<ProductAttribute>;
attrs.Add(Color.Blue);
attrs.Add(Color.Green);
attrs.Add(Color.Blue); // no problem
attrs.Add(Color.GetColor("blue")); // no problem
attrs.Add(Size.Small);
attrs.Add(Size.Medium);
attrs.Add(Size.Medium); // no problem
使用 ProductAttribute
classes 的一种方法如下:
foreach (ProductAttribute attr in attrs) {
Color color = attr as Color;
if (color != null) {
// work with color
}
}
或者,您可以创建一个 ProductAttributeType
枚举,将其作为参数添加到 ProductAttribute
构造函数中,并在 ProductAttribute
中以只读摘要 属性 公开它=] class。然后你所有的 subclasses 都传递它们是什么类型,你可以很容易地得到正在做的事情的类型 attr.ProductAttributeType == ProductAttributeType.Color
例如。
我不确定您的用例,NameValueCollection
允许重复项更好地用于此类情况 Dictionary
。
您仍然可以在 NameValueCollection
上执行类似的操作以获得您想要的结果。
var results = nvc.AllKeys
.GroupBy(g=>g)
.Select(s=>
new
{
key = s.Key,
values = nvc.GetValues(s.Key).Distinct()
});
foreach(var result in results)
{
Console.WriteLine("{0}- {1}", result.key, string.Join(",", result.values) ;
}
工作Example
老问题,但我需要类似的东西(在 VB.Net 中,但在 C# 中很容易应用);我正在使用该集合编译 words/word 组和值之间的引用,同时忽略大小写。字典解决方案会覆盖值,只维护最后一个值,并且绑定到列表的字典变得比我喜欢的更麻烦。为了准确了解所要求的内容,我首先使用以下语法添加:
If Not nvc.AllKeys.Contains(name) OrElse Not nvc.GetValues(name).Contains(value) Then nvc.Add(name, value)
大量重复调用相同的键和值不会非常有效,但这可能是我能找到的最简单的方法。这最终变得多余,并且在我的代号中(有时甚至是值)是临时构建的;为了尽可能减少 code/variables 并提高效率(仍然使用这种效率低下的方法),我首先考虑构建一个
Private Class NoDupValueNameValueCollection
Inherits Collections.Specialized.NameValueCollection
Public Overrides Sub Add(name As String, value As String)
If Not MyBase.AllKeys.Contains(name) OrElse Not MyBase.GetValues(name).Contains(value) Then MyBase.Add(name, value)
End Sub
End Class
或 C#
private class NoDupValueNameValueCollection : System.Collections.Specialized.NameValueCollection {
public override void Add(string name, string value) {
if (!(base.AllKeys.Contains(name)) || !(base.GetValues(name).Contains(value))) base.Add(name, value);
}
}
它现在可以代替 nvc 使用,并且与 nvc 完全一样,并且可以防止重复值。事实上,这正是所要求的:防止添加重复值的 NameValueCollection