Help understanding some C# code
Can someone please explain to me the following method? I don't quite understand what it does, and how it does it.
private List<Label> CreateLabels(params string[] names)
{
return new List<Label>(names.Select(x =>开发者_如何学Python new Label { ID = 0, Name = x }));
}
Let's separate it into different bits:
private List<Label> CreateLabels(params string[] names)
This means we're declaring a method returning a list of Label
references. We're taking an array of string references as a parameters, and it's declared as a parameter array which means callers can just specify the arguments like this:
List<Label> labels = CreateLabels("first", "second", "third");
(Or they can explicitly pass in an array of strings as normal.)
Now to understand the body, we'll split it up like this:
IEnumerable<Labael> labels = names.Select(x => new Label { ID = 0, Name = x });
List<Label> list = new List<Label>(labels);
return list;
The second and third lines should be fairly simple - it's just constructing a List<Label>
from a sequence of labels, and then returning it. The first line is likely to be the one causing problems.
Select
is an extension method on the generic IEnumerable<T>
type (a sequence of elements of type T
) which lazily returns a new sequence by executing a projection in the form of a delegate.
In this case, the delegate is specified with a lambda expression like this:
x => new Label { ID = 0, Name = x }
That says, "Given x
, create a Label
and set its ID property to 0, and its Name
property to x
." Here the type of x
is inferred to be string
because we're calling Select
on a string array. This isn't just using a lambda expression, but also an object initializer expression. The new Label { ID = 0, Name = x }
part is equivalent to:
Label tmp = new Label();
tmp.ID = 0;
tmp.Name = x;
Label result = tmp;
We could have written a separate method to do this:
private static Label CreateLabel(string x)
{
Label tmp = new Label();
tmp.ID = 0;
tmp.Name = x;
return tmp;
}
and then called:
IEnumerable<Label> labels = names.Select(CreateLabel);
That's effectively what the compiler's doing for you behind the scenes.
So the projection creates a sequence of labels with the names given by the parameter. The code then creates a list of labels from that sequence, and returns it.
Note that it would (IMO) be more idiomatic LINQ to have written:
return names.Select(x => new Label { ID = 0, Name = x }).ToList();
rather than explicitly creating the List<Label>
.
In general, the meaning behind well written code can often be deduced by the code itself. This is called "self-documenting code." Code that doesn't follow this, should hopefully be accompanied by comments.
In this case, here is how you could figure out what the code does:
The method gives you some key bits of information:
The name of the method. This lets you know what the method does. In this example, the method is called
CreateLabels
The method's signature. This indicates what the method requires. In this example, there is an array of type string, with the keyword
params
. The keywordparams
indicates that this method will accept one or more names as inputs to the method, and will collect them into a single array.The method's return type. This will tell you want the method will give you when it's finished. In this example, it returns a List of Labels.
So, since the method is called CreateLabels
, takes an series of string called names, and returns a list of lables, we might say that "Given several names, this method will return a list of lables"
Now if you need to know how the method is doing this, then have a look at the body.
return new List<Label>(names.Select(x => new Label { ID = 0, Name = x }));
For someone who does not understand linq or lambda expressions, this is a bit difficult to understand.
Lets work our way from outside to inside:
return new List<Label>()
constructs a new list and returns the new list, and causes the method to exit.
names.Select()
Is a method that will apply a set of operations to all the objects in the array, and return a new collection which will contain the result of applying those operations.
x=>new Label {ID = 0, Name = x}
is a lambda expression that says: x goes to a new Label object who's ID field is 0, and Name is the value of x
.
Putting it all together, the statement return new List<Label>(names.Select(x => new Label { ID = 0, Name = x }));
is creating a new Label Object for each name in names
and stores it into a new list, which is returned at the end of the method.
It is a way of also writing:
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;
This simply takes a variable sized set of names, and turns them into a list of labels with the ID set to 0.
List<Label> labels = CreateLabels("one", "two", "three");
foreach(Label label in labels)
{
Console.WriteLine(label.Name);
Console.WriteLine(label.ID);
}
This will print:
one
0
two
0
three
0
This code returns collection (List
) of Label
classes. Foreach string variable in input parameter names
it creates new instance of class Label with ID property equal to 0 and Name property equal to current names
element
You can change this code to following:
private List<Label> CreateLabels(params string[] names)
{
List<Label> result = new List<Label>();
foreach(string name in names)
{
Label label = new Label()
label.ID = 0;
label.Name = name;
result.Add(label);
}
result;
}
you need to learn this linq 101 sample then you know yourself the meaning of this code.
Ok, here goes:
new Label { ID = 0, Name = x }
This is creating a new instance of Label
with ID
set to 0 and Name
set to x
.
x => new Label { ID = 0, Name = x }
This is called a lambda expression - it is defining an anonymous function which accepts a single input (x
) and returns a new instance of label. You may find it easier to read x => ...
as "x
goes to ...".
names.Select(x => new Label { ID = 0, Name = x })
This is calling the Select
method on the names
object, passing the above lambda expression as a parameter. We can see that the type of names
is a string
array. This is in fact an extension method - string[]
does not define a method Select
, this the Select method (here on MSDN) is defined elsewhere (in the System.Core
assembly)
The select method simply "Projects each element of a sequence into a new form." - essentially it converts each element in the array into another object (in our case an instance of Label
)
To clarify: The above statement returns an IEnumerable (a kind of collection) of Label
objects, one for each string in names
.
return new List<Label>(...);
This returns a new List of Label
objects - in our case we are passing in our IEnumeable returned by the call to Select
.
In short:
This method outputs a List of Label
objects, one for each string in names
. Each Label
object has its ID
set to 0
, and its Name
set to the string value from the names
array.
Does this help explain what's going on here?
精彩评论