I found this sample of code on SO (can't remember from where :/) that allowed me to check for line code arguments when launching my application :
if (e.Args.Length == 0 || e.Args.Any("-show".Contains))
{
//show interface...
}
I just can't seem to understand how the "-show".Contains works.
And if there's any difference with a (classic) x => x.Contains('"-show") (except for the evident typing gain).
Works like a charm but I'd like to understand why, I feel like something big is hapening.
This:
.Any("-show".Contains)
is basically shorthand for this:
.Any(s => "-show".Contains(s))
The Any method takes a delegate as a parameter and you can create that delegate in a number of ways. The first snippet uses a method group while the second uses a Lambda.
It's not really accurate to say that the first is shorthand for the second because method groups predate Lambdas, but if you think in terms of Lambdas when calling LINQ methods like Any then it is effectively the case.
As #jmcilhiney already said, it shorthand for:
.Any(s => "-show".Contains(s))
Contains is a function accepting 1 parameter which is of type string (and returns a boolean). Any() in this case wants a function that needs 1 param which is a string and that returns a boolean. So rather than adding an extra lambda warapper s=>, you can directly return .Contains
In technical terms this is a:
Func<string, boolean> //1 param string, output: boolean
Note that this code matches any argument that is a part of -show
thus either of the following arguments do match!
-show
-s
sh
ow
h
w
// etc..
Any() expects a Func<TSource, bool> delegate. So any function that returns a bool and takes an argument that is of the same type as the elements of the collection (string in your case) can be applied. This can be an existing function, or a lambda expression.
The signature of String.Contains is
bool Contains(string s)
That's why you can pass it to Any()
The equivalent would be x => "-show".Contains(x) rather than what you've shown.
After that you'll realise that all you're doing by introducing the x based lambda is to create a function accepting a single string argument and returning a bool and wrapping a function that accepts a single string and returns a bool. There's no need for the wrapper.
Related
I really enjoy using the aggregate functions that C# provides such as .Any(), but I struggle to understand what my options are just looking from the method signature:
Can someone help me better understand the meanings of (Func predicate)? I know that I normally use a lamda fucntion here. But, how that translates back into whatever Func is, I don't understand.
(extension) bool IEnumerable<string>.Any<string>(Func<string, bool> predicate)(+ 1 overload)
Determines whether any element of a sequence satisfies a condition.
Exceptions:
ArgumentNullException
Means:
You can call this as an extension method.
On an IEnumerable<string>, that is something you can iterate on that gives you string. string is type that holds text.
The name of the method is Any
It has a type argument, which is set to string. You probably can call this on a IEnumerable<T> where T is something other than string.
It takes a Func<string, bool> predicate, that is a delegate to a function that takes a string as input parameter and returns a bool.
There is another overload of the method, which takes different arguments.
The method documentation says it "Determines whether any element of a sequence satisfies a condition." We can presume it goes over the IEnumerable<string> calls the Func<string, bool> passing the string from the IEnumerable<string> passing each value, and returns whether or not it got true for any one of them.
The method is documented to throw an ArgumentNullException, presumubly if you pass a null.
If we look online for it, we find in the official documentation Enumerable.Any. There we can see the other overload and also some examples.
Here is one:
Pet[] pets =
{ new Pet { Name="Barley", Age=8, Vaccinated=true },
new Pet { Name="Boots", Age=4, Vaccinated=false },
new Pet { Name="Whiskers", Age=1, Vaccinated=false } };
// Determine whether any pets over age 1 are also unvaccinated.
bool unvaccinated =
pets.Any(p => p.Age > 1 && p.Vaccinated == false);
We see an array of Pet, and we call Any on it. Thus, in this case the type argument is Pet instead of string, given that an array of Pet is a thing over which you can iterate and it gives you elements of type Pet... I'm saying that an array of Pet is an IEnumerable<Pet>... and thus we are calling Any<Pet>.
We observe that the parameter is a lambda expression: p => p.Age > 1 && p.Vaccinated == false
This lambda represents an anonymous function that takes an argument p. Since we know that we are using Any<Pet>, and we know that Any<Pet> wants a delegate to a function that takes a Pet and returns bool, we know that p is a Pet.
The anonymous function takes the Pet p compares the property Age with 1 and the property Vaccinated with false, and return true if Age is greater than 1 and Vaccinated is false.
Looking at the values in the array, we can see that the second item (the one of Name "Boots") has Age greater than 1 and Vaccinated is false. Thus, the anonymous function should return true for that Pet.
And given that Any return true if the predicate (the anonymous funciton) was true for any of the elements, we expect Any to return true in this case. The description of the example and expected output in the official documentation confirms this.
If we still have the doubt, we can, of course, try running the code: code on SharpLab. The expected output is "There are unvaccinated animals over age one.".
If you want to go one step deeper, you can search the reference implementation of Enumerable.Any.
If you know where to look, you can get the .NET Core source for Enumerable.Any, Not guaranteed to stay there, refectoring could put it somewhere else.
You may also be interested in the documentation about extension methods.
See also What is Func, how and when is it used.
But, how that translates back into whatever Func is?
Well, first we need to know what Func is.
Let's see how Func is declared:
public delegate TResult Func<in T,out TResult>(T arg);
We can see that Func is a delegate. If you don't know what a delegate is, there are wonder pages out there that tell you about them: 1, 2, 3.
How is related to the lambda expression you pass in?
The declaration says that Func is a delegate that takes a parameter of type T, and returns a TResult. From the signature of Any, we can see that T is string while TResult is bool in this particular case.
This means that you can convert a lambda expression, (or a method group,) that takes a string as a parameter and returns bool to an instance of Func<string, bool>.
Let's say you call Any like this:
something.Any(x => x.Length > 10)
From the parameter type, the compiler infers that the lambda expression must take a string, so the type of x must be string. And the lambda expression must also return a bool, which it does, so we're good! The lambda expression is converted to an instance of Func<string, bool>.
What's it called when a method that takes a lambda expression as the parameter, such as Enumerable.Where, is invoked without actually declaring a variable or method parameter in the expression?
For example, I'm familiar with this lambda expression syntax:
public string GetDigits(string input)
{
return new String(input.Where(i => Char.IsDigit(i)).ToArray());
}
However, I was surprised to find out that this can also be written as:
public string GetDigits(string input)
{
return new String(input.Where(Char.IsDigit).ToArray());
}
What's going on in that second snippet, where the Char.IsDigit() method is (apparently) being called with an implicit parameter? What is this syntax called?
Methods don't accept lambdas as parameters. They accept delegates as parameters. A lambda is just one way of creating a delegate.
Another way is supplying a method group, as is done in your second example, which can be converted to a delegate.
A similar way is to use the anonymous method feature. This was more or less replaced with lambdas when they were added though, so you don't see it much. Your example using that syntax would be:
Func<char, bool> predicate = delegate(char c) { return Char.IsDigit(c); };
Yet another way would be to create a delegate using Delegate.CreateDelegate. (This isn't something you see all that often though.)
A final way is to have a delegate variable that you got from somewhere else. (That somewhere else would have created the delegate using one of these other options.)
What's going on in that second snippet, where the Char.IsDigit() method is (apparently) being called with an implicit parameter? What is this syntax called?
It's not being called. That's the whole point. We're trying to create a delegate. A delegate is an object that keeps track of a method to be invoked, and an object that it should be invoked on. You can then invoke the delegate and it will call the method that was used to create it. So here you're not calling IsDigit, you're creating a delegate that is pointing to the IsDigit method, and that will call it whenever that delegate is invoked.
When you use a lambda you're creating a new method, possibly in a new class, (neither of which have a name you can refer to, but they'll have one at runtime) and the body of that anonymous method will call IsDigit. The lambda then resolves to a delegate pointing to that anonymous method, which maintains the semantics of the other example of having a method that when called, calls an anonymous method which, in its implementation, calls IsDigit. It's adding an extra layer of indirection (that may or may not just get optimized out at runtime) to accomplish the same thing.
The signature of Enumerable.Where is:
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
This:
input.Where(i => Char.IsDigit(i))
is equivalent to writing:
Func<char, bool> temp = i => Char.IsDigit(i);
input.Where(temp);
so it creates an anonymous function with a parameter i that calls Char.IsDigit.
This:
input.Where(Char.IsDigit)
is equivalent to
Func<char, bool> temp = Char.IsDigit;
input.Where(temp);
that is equivalent to:
Func<char, bool> temp = new Func<char, bool>(Char.IsDigit);
input.Where(temp);
so it creates a delegate to Char.IsDigit and then passes it to input.Where.
So the second one removes the "man-in-the-middle" (the anonymous function). In this particular case it is "legal" because the i parameter of the anonymous function is passed "as is" to Char.IsDigit. It would have been different if it was:
input.Where(i => !Char.IsDigit(i))
in this case, you can't remove the man-in-the-middle (the anonymous function).
There is no name for all of this (or you could call the first "creating and passing a delegate to an anonymous function" and the second "creating and passing a delegate created from a method group"... but they aren't beautiful catchphrases, they are more a description of what you are doing)
Because the compiler will implicitly cast the method group to a delegate if it finds a single method that matches the expected signature, in this case a delegate taking a single char as input and returning a bool.
Your Where expects a Func<char, bool>, which is a delegate for methods that take a char argument and return a bool. Anything that matches this delegate is a valid argument for this Where.
The lambda you wrote initially matches this delegate by type inference: the compiler expects that i is char, based on the generic parameter of the enumerable source - and infers the return type as bool, because that's what the method call expression inside the lambda would return.
The Char.IsDigit method itself also matches this. Thus, referencing the method is another valid way of expressing the same thing. This is called a method group.
The semantic equivalence of these two possible arguments for Where also makes sense if you consider that for every lambda expression, the compiler generates an anonymous method and then passes that anonymous method where the delegate was expected.
To illustrate this, consider your original snippet:
Where(i => Char.IsDigit(i))
The above gets lowered by the compiler to:
bool AnAnonymousMethod(char i)
{
return Char.IsDigit(i);
}
and then:
Where(AnAnonymousMethod)
As you can see, the lambda syntax (in cases where you don't have captured variables, like here) is just syntactic sugar for writing an anonymous method and then using the method group of this newly written method as the argument wherever a compatible delegate is expected.
What does = () => mean in c#?
I've used lambda's before but those empty parens () are throwing me off.
Familiar with this:
customers.Find(x=>x.FirstName=="John")
Article resource
It's assigning a lambda expression to the variable or property this.Implementation. You have to break down the operators like this:
this.Implementation
= //assignment operator
()=> new Sequence { /* stuff */ };
The () is to designate that the method takes no parameters; the => identifies what follows as the code to be run when the lambda is invoked.
The () simply means the anonymous method has no parameters. The way you're used to seeing, like customers.Find(x=>x.FirstName == "John") is the same... the first x is the parameter passed to the lambda. The parentheses are optional if there's only a single parameter, so this could also be written like this: customers.Find((x)=>x.FirstName == "John") With a method that takes no parameters, the 'single parameter' exclusion doesn't apply, so you have to write the (). You can see more in the documentation.
The = before the lambda call is assigning the method body that follows to the Implementation property.
This is known as a lambda expression. In essence, it's shorthand for defining a function.
Here is a decent tutorial explaining the concept:
http://www.dotnetperls.com/lambda
The () => new Sequence part along with the block below it is an lambda function that takes no parameters and return a Sequence
This lambda is assigned to this.Implementation so that at a later time you can call the lambda. E.g., var s = this.Implementation().
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am really confused to understand its internal working
This is LINQ syntax
string[] test = new test[] { "abc", "", "cd", "", "aa" };
test = test.Where(x => !string.IsNullOrEmpty(x)).ToArray();
I am confused about where syntax how it manages. is it put all array in x? if yes then how it manage x null value?
or
if not then test array values put one by one in the x?
You should consider the rest of the answers, they are pretty accurate, what I want to show you and maybe this will help you to understand the syntax is that this kind of query can actually be represented in a query syntax like this:
string[] test=new test[]{"abc","","cd","","aa"};
// this is the equivalent to your code
// added explicit type to make it clearer, it's optional
var a = from (string)x in test
where !string.IsNullOrEmpty(x)
select x;
if you are familiar with SQL, you will find this syntax easier to read, even when you do not know it, this syntax is cleaner.
When the code is compiled, this query syntax is automatically translated to the C# method syntax, in order to generate the IL, so if you dissasmbly a DLL you will see the method syntax instead of the query syntax
A brief explanation about this code:
As you can see an x variable was declared and it's of type string. Why? because your array is an array of strings
The in test indicates the source IEnumerable<> to iterate - your array in this case
The where is pretty explanatory, it simply selects all not null strings from your array
And finally the selects which actually is a projection of the data.
And all this is equivalent to your code
Now you might be asking yourself... When should I use one syntax or the other? Well they are equivalent but the query syntax operators are limited which means that most of the operations are done with method syntax instead of query syntax. What I always do is try to write the code easier to read some code is easier to understand if it is written with a query syntax.
About the method syntax, the x => ... syntax is known as lambda expression, they might look weird if it is the first time you are working with them but you will love them eventually.
Basically lambdas are shortcuts to delegates, so what you are doing with:
x => !string.IsNullOrEmpty(x)
You are creating an anonymous method and the method is being assigned to the delegate parameter. The x represents the string variable.
This topic is really extensive to try to explain it here, but I hope this has given you an idea of what's behind.
Btw you can combine the syntax's like this:
// this is the equivalent to your code
// added explicit type to make it clearer, it's optional
var a = (from (string)x in test
where !string.IsNullOrEmpty(x)
select x).ToArray();
If you google LINQ is like googling porm lol the web is plagued with LINQ articles, samples, etc.
A good point of start would be the 101 samples from Microsoft
http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
EDIT
I will try to emulate the Where method so you can have a better example of the lambda expression
// this is basically the declaration of one overload of the Where method
// the this in the parameter declaration, indicates this is an extension method which will be available to all IEnumerable<> objects
// the Func<T, bool> is the interesting part, it is basically a delegate (as a reminder, the last parameter of the Func object indicates the type that must be returned, in this case is a bool)
// the delegate is simply a pointer to a function
public IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
...some logic
... yielding back the reuslts
foreach(var r in res)
{
// here is the delegate in action
if(predicate(r))
yield return r;
}
}
As you can see the delegate was called as a function (delegates are pointer to functions)
Butt what function??? the one you declared in your code
x => !string.IsNullOrEmpty(x) and the x indicates the parameter passed back from the Where method to the external code, where you can inspect it and use it to filter your results
The x => is an abbreviation to declare a delegate
!string.IsNullOrEmpty(x) this is the body of your anonymous method and as you can see it fulfills the requirements of the Func<T, bool> it is returning a bool (the predicate to filter the elements of the array) and as a parameter, it received the generic T which in this case is a string from your array
Another way to declare the lambda expression is:
test = test.Where(
(string) x =>
{
return !string.IsNullOrEmpty(x)
})
.ToArray();
With this syntax is easy to show that they are actually methods (anonymous methods)
we can take the statement apart and examine the pieces one at a time
x => !string.IsNullOrEmpty(x) is basically defining a function like the below
bool Filter(string x){
return !string.IsNullOrEmpty(x)
}
and creates a Predicate based on that function. A predicate is just a delegate - a function you can pass in a variable.
.Where is an extension method that for simplicity could be defined
IEnumerable<T> Where<T>(this IEnumerable<T> sequence,Predicate<T> pred){
foreach(var elem in sequence){
if(pred(elem)){
yield return elem;
}
}
}
had you defined the function as Filter is defined above instead of using a lambda your statement would look like this
test = test.Where(Filter).ToArray();
so by calling this extension method on your array and passing the above predicate you will iterate over all elements in the array and return all those elements that matches the predicate (Ie. those that are neither null nor have the value of the empty string)
Finally you call the extension method .ToArray() which turns what .Where returned (an IEnumerable<string>) into an array
EDIT
Read this article you will surely get good idea about that you have writtnen......
C# 3.0 New Language Features (Part 1)
C# 3.0 New Language Features (Part 2)
it's from of extenstion method + lambda experssion part of C# 3.0
here in this code
test=test.Where(x => !string.IsNullOrEmpty(x)).ToArray();
where - is a extesion method
x => !string.IsNullOrEmpty(x) - is lambda expresion , which is replacement of anonymous function
this whole function check the each element of array ...i.e the lamdaba expression check the each element of the array satisfy the conditon which is written and than finally retuns array of those element which satisfy the condition
I have noticed something odd with linq and the Contains method. It seems to get confused on which Contains method to call.
if (myString.Contains(strVar, StringComparison.OrdinalIgnoreCase))
{
// Code here
}
The above code doesn't compile with the following error:
The type arguments for method 'System.Linq.Enumerable.Contains(System.Collections.Generic.IEnumerable, TSource, System.Collections.Generic.IEqualityComparer)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
If I remove the using linq statement it is happy with the contains (but brakes all the linq code).
What is the correct syntax to tell the compiler I want to use the String.Contains method and not Linqs?
Cheers
This is because there's no String.Contains(string, StringComparison) method defined in the BCL and the compiler tries to use an extension method. There's only String.Contains(string) method defined.
What is the correct syntax to tell the compiler I want to use the String.Contains method and not Linqs?
There is no overload of String.Contains that accepts a StringComparision. You might want to use String.IndexOf(string, StringComparison):
// s is string
if(s.IndexOf(strVar, StringComparison.OrdinalIgnoreCase) >= 0) {
// code here
}
It could be because the string.Contains method takes only one parameter (a string; there is no overload of string.Contains that takes a StringComparison value), while the Enumarable.Contains extension method takes two. However, the parameters that you supply do not fit the expected input types, so the compiler gets confused.
As Darin Dimitrov said, String.Contains(string, StringComparison) does not exist as a method for the String type.
System.Linq.Enumerable however does contain such a signature. And a string is also an IEnumerable<char>, that's why the compiler gets confused. You would actually be able to leverage Linq and compile if you replaced the StringCompar-ison with an ICompar-er of Char:
if (myString.Contains(strVar, Comparer<Char>.Default))
{
// Code here
}