I am learning C# myself and I wonder if C# method can quickly parse a list of values just like Python does as below:
def myMethod(somevalue):
return somevalue * 2
x = [1,2,3,4,5]
a = [myMethod(i) for i in x]
Currently I am trying to make a class that has a method that takes in a double. But what if x is a list?
class myClass
{
public double somevalue;
public myClass(double someValue)
{
somevalue = someValue;
}
public double myMethod()
{
return somevalue * 2;
}
}
myClass output = new myClass(x);
A = output.myMethod();
My question is, can C# create very concise codes that makes the Method takes in the list, loop through the list and gives out a list of results?
CodePudding user response:
Not a python expert but this:
def myMethod(somevalue):
return somevalue * 2
x = [1,2,3,4,5]
a = [myMethod(i) for i in x]
Looks like it would be this in C#:
//either:
double TimesTwo(double d) => d * 2; //a method declaration that is "expression bodied" style
//or:
double TimesTwo(double d) { return d * 2; } //a method declaration that is "normal" style
void SomeOtherMethod(){ //these statements can't just be floating around in a namespace like the method declarations above, they have to be inside some other method
var x = new[] {1d,2,3,4,5}; //the first element is a double (1d), the others will be promoted from int to double without needing an explicit cast, the whole array x is a double[]
var a = x.Select(TimesTwo).ToArray();
}
You can skip creating a separate method for the * 2
operation (the method above is called TimesTwo) and just put the logic of what you want inline:
var x = new[] { 1d,2,3,4,5 };
var a = x.Select(p => p * 2).ToArray();
The p => p * 2
is something like an "inline method" - we refer to them as lambdas; the input argument is called p
and its type is inferred from the type of the collection that .Select
is called on. In this case a double
is inferred, because x
is a double
array
The return
keyword is not specified in a single line lambda (which we refer to as an expression bodied something); the single line of code after the =>
(in both p => ...
and TimesTwo(int i) => ...
) is a statement that resolves to a value, and that value is implicitly returned. In this case the statement p => p * 2
multiplies input p
by 2 and the result is returned automatically.
The result of the .Select
method is an enumerable (specifically of type IEnumerable<double>
, and the ToArray()
method will enumerate it and turn it into an array. It is the calling of ToArray that causes p*2
to be invoked on every member, and ToArray collects all the results and outputs an array
All this code comes from extension methods in the System.Linq
namespace, so your code needs using System.Linq;
at the top
One important point, that may well bite at some time in the future; the code in the lambda within the Select is not performed if the enumerable output by the Select is not actually enumerated. If you had:
var enumerableThing = oneThousandThings.Select(p => SomeOperationThatTakesOneSecond(p));
It would execute near instantly; nothing in that line of code enumerates the resulting enumerable, no memory is allocated for a new array, no looping over collections of anything occurs, the operation that takes 1 second is not even called once let alone a thousand times.
If you later did something that actually enumerated the result, then the operation would take a thousand seconds:
var arr = enumerableThing.ToArray() //takes 1000s
foreach(var x in enumerableThing) //would take 1000s to finish looping
...
int i = 500;
foreach(var x in enumerableThing){ //would take 500s, the enumeration quitting early after being half done
i--;
if(i == 0) break;
}
This enumerating could be done hours or days later; it's called deferred execution and is worth looking into further if you're not familiar with it
CodePudding user response:
You would use System.Linq.Enumerable.Where()
to filter the List
var filtered = x.Where(y => myMethod(y)).ToList();
or Select
to convert the list
var converted = x.Select(y => myMethod(y)).ToList();