我很好奇下面的代码如何工作,特别是包含委托内容的部分,因为我是新手。此外,代码中是否存在任何瓶颈,例如,使用SortedDictionary会比使用List更好,然后使用LINQ对其进行排序?好的,这是代码:
public class ColorManager
{
private List<ColorData> colorCodes = new List<ColorData>();
public List<ColorData> ColorCodes
{
get
{
var sortList = from a in this.colorCodes
orderby a.colorCode ascending
select a;
return sortList.ToList();
}
}
public void FillData(DataTable table)
{
for(int row = 0; row < table.Rows.Count; row++)
{
ColorData cData = new ColorData();
string name = table.Rows[row]["Color"].ToString().Trim();
if(!this.colorCodes.Exists(
delegate(ColorData e)
{
return e.ColorCode == name;
}))
{
cData.Add(table.Rows[row]["Color"].ToString());
this.colorCodes.Add(cData);
}
else
{
this.colorCodes.Find(
delegate(ColorData e)
{
return e.ColorCode == name;
}).Count++;
}
}
}
}
答案 0 :(得分:2)
我很好奇以下代码是如何工作的,特别是包含代理内容的部分,因为我是新手。
首先看一下这个ColorCodes
属性访问器:
var sortList = from a in this.colorCodes
orderby a.colorCode ascending
select a;
它以升序(this.colorCodes
)返回所有颜色代码(...orderby a.colorCode ascending
)的列表。到目前为止简单。如何更加方便FillData
方法?
首先,我们将遍历此表中的每一行:
for(int row = 0; row < table.Rows.Count; row++)
{
然后,我们将查看当前行的Color
列。
ColorData cData = new ColorData();
string name = table.Rows[row]["Color"].ToString().Trim();
如果该列在颜色代码列表中不匹配,则此if
条件为真。 Exists
方法采用单参数函数返回bool,这是匿名委托的内容:单参数(ColorData e
)函数返回一个布尔值(e.ColorCode == name
)。它被否定(!this.[...]
),因此如果找到匹配,则条件为假。
if(!this.colorCodes.Exists(
delegate(ColorData e)
{
return e.ColorCode == name;
}))
{
cData.Add(table.Rows[row]["Color"].ToString());
this.colorCodes.Add(cData);
}
否则,如果匹配,请使用另一个匿名委托查找名称,并在该颜色的项目数中添加一个。
else
{
this.colorCodes.Find(
delegate(ColorData e)
{
return e.ColorCode == name;
}).Count++;
}
}
请注意,此代码效率有点低,因为两个不同的匿名委托实际上做同样的事情并且可以共享。
答案 1 :(得分:2)
实际上,那里的代表比你期望的多。 LINQ查询:
var sortList = from a in this.colorCodes
orderby a.colorCode ascending
select a;
实际上是:
var sortList = this.colorCodes.OrderBy(a => a.colorCode);
(对于LINQ-to-Objects)与:
相同var sortList = this.colorCodes.OrderBy(delegate (ColorData a) {
return a.colorCode;
})
这使用委托来识别要排序的项目 - 即“给定ColorData,我会给你colorCode”。请注意,许多select
使用也涉及委托,但在这种情况下不会(编译器删除了普通的select a
。)
在代码中:
if(!this.colorCodes.Exists(
delegate(ColorData e)
{
return e.ColorCode == name;
}))
我们正在使用谓词; “给定一个ColorData,我会告诉你它是否匹配,通过测试名称是否相等”。请注意,name
这里被“捕获”到委托中,这涉及一些相当复杂的编译器技巧(我不会描述它们)。
效率;很难确定,但也许:
Dictionary<string, ColorData> items = new Dictionary<string, ColorData>();
foreach(DataRow row in table.Rows) {
string name = row["Color"].ToString().Trim();
ColorData cData;
if (items.TryGetValue(name, out cData)) {
cData.Count++;
} else {
cData.Add(name);
colorCodes.Add(cData);
items.Add(name, cData);
}
}
这避免了大量重复,并使用字典查找值而不是经常使用Contains / Find。在许多情况下,LINQ GroupBy
可能有所帮助,但在这种情况下可能没有。
答案 2 :(得分:0)
它是一个匿名委托,作为查找表达式的选择标准。换句话说,如果颜色等于name给出的颜色,它将返回true,Find将把它添加到它正在生成的IEnumerable中。如果返回false,则Find将不包含它。
可以更简洁地写出来p => p.ColorCode == name
答案 3 :(得分:0)
存在和查找是通用扩展方法。它们用于集合中每个项目的每个循环。传递委托一个参数(定义为“(ColorData e)”),并返回一个布尔值。
答案 4 :(得分:0)
代表:
此示例中的委托正在实现Func方法。基本上,你正在做的是创建一个采用ColorData参数的方法,并返回一个bool。
这使您可以对IEnumerable集合的每个成员执行Exists()和Find()调用以进行检查和过滤。
排序词典:
如果这是你使用它的唯一地方,你最好使用SortedDictionary,因为你不会经常使用它。现在,每次你打电话给ColorCodes,你都会使用。 SortedDictionary将不断排序。