帮助理解一些C#代码

lea*_*ing 7 c#

有人可以向我解释以下方法吗?我不太明白它的作用,以及它是如何做到的.

private List<Label> CreateLabels(params string[] names)
{
    return new List<Label>(names.Select(x => new Label { ID = 0, Name = x }));
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 18

让我们将它分成不同的位:

private List<Label> CreateLabels(params string[] names)
Run Code Online (Sandbox Code Playgroud)

这意味着我们声明了一个返回Label引用列表的方法.我们将一个字符串引用数组作为参数,并将其声明为参数数组,这意味着调用者可以像这样指定参数:

List<Label> labels = CreateLabels("first", "second", "third");
Run Code Online (Sandbox Code Playgroud)

(或者他们可以正常传递一个字符串数组.)

现在要了解身体,我们将它分开:

IEnumerable<Labael> labels = names.Select(x => new Label { ID = 0, Name = x });
List<Label> list = new List<Label>(labels);
return list;
Run Code Online (Sandbox Code Playgroud)

第二行和第三行应该相当简单 - 它只是List<Label>从一系列标签构建一个,然后返回它.第一行可能是导致问题的那一行.

Select是泛型类型(类型的元素序列)的扩展方法,它通过以委托形式执行投影来延迟返回新序列.IEnumerable<T>T

在这种情况下,委托使用如下的lambda表达式指定:

x => new Label { ID = 0, Name = x }
Run Code Online (Sandbox Code Playgroud)

这就是说,"给定x,创建一个Label并将其ID属性设置为0,并将其Name属性设置为x." 这里x推断的类型是string因为我们正在调用Select一个字符串数组.这不仅使用lambda表达式,还使用对象初始化表达式.该new Label { ID = 0, Name = x }部分相当于:

Label tmp = new Label();
tmp.ID = 0;
tmp.Name = x;
Label result = tmp;
Run Code Online (Sandbox Code Playgroud)

我们本可以写一个单独的方法来做到这一点:

private static Label CreateLabel(string x)
{
    Label tmp = new Label();
    tmp.ID = 0;
    tmp.Name = x;
    return tmp;
}
Run Code Online (Sandbox Code Playgroud)

然后叫:

IEnumerable<Label> labels = names.Select(CreateLabel);
Run Code Online (Sandbox Code Playgroud)

这实际上是编译器在幕后为您做的事情.

因此,投影会创建一系列标签,其名称由参数指定.然后代码从该序列创建标签列表,并返回它.

请注意,它(IMO)会更加惯用LINQ来编写:

return names.Select(x => new Label { ID = 0, Name = x }).ToList();
Run Code Online (Sandbox Code Playgroud)

而不是明确地创建List<Label>.


Ala*_*lan 9

一般来说,编写良好的代码背后的含义通常可以由代码本身推断出来.这称为"自我记录代码".不遵循此规范的代码应该伴随着评论.

在这种情况下,您可以通过以下方式找出代码的作用:

该方法为您提供了一些关键信息:

  • 方法的名称.这可以让您知道该方法的作用.在此示例中,调用该方法CreateLabels

  • 方法的签名.这表明该方法需要什么.在此示例中,有一个类型为string的数组,其中包含关键字params.关键字params表示此方法将接受一个或多个名称作为方法的输入,并将它们收集到单个数组中.

  • 方法的返回类型.这将告诉您希望方法在完成时给您.在此示例中,它返回标签列表.

因此,由于该方法被调用CreateLabels,需要一系列名为name的字符串,并返回一个标签列表,我们可能会说"给定几个名称,这个方法将返回一个标签列表"

现在,如果你需要知道方法是如何做到的,那么看看正文.

return new List<Label>(names.Select(x => new Label { ID = 0, Name = x }));

对于不了解linq或lambda表达式的人来说,这有点难以理解.

让我们从外到内工作:

return new List<Label>() 构造一个新列表并返回新列表,并使该方法退出.

names.Select() 是一种方法,它将一组操作应用于数组中的所有对象,并返回一个新的集合,其中包含应用这些操作的结果.

x=>new Label {ID = 0, Name = x}是一个lambda表达式,表示:x转到一个新的Label对象,其ID字段为0,Name为值x.

总而言之,该语句return new List<Label>(names.Select(x => new Label { ID = 0, Name = x }));为每个名称创建一个新的Label对象,names并将其存储到新的列表中,该列表在方法结束时返回.

这是一种写作方式:

List<Labels> toReturn = new List<Labels>();
foreach(string name in names)
{
 Label l = new Label();
 l.ID = 0;
 l.Name = name;
 toReturn.Add(l);
}
return toReturn;
Run Code Online (Sandbox Code Playgroud)


Mer*_*ham 6

这只需要一组可变大小的名称,并将它们转换为ID设置为0的标签列表.

List<Label> labels = CreateLabels("one", "two", "three");
foreach(Label label in labels)
{
    Console.WriteLine(label.Name);
    Console.WriteLine(label.ID);
}
Run Code Online (Sandbox Code Playgroud)

这将打印:

一个
0
两个
0
三个
0