I was reading some code and saw the following:
Method.Find(delegate(Department depts) {
return depts.Id == _departmentId; });
The T Find method has the following description:
public T Find(Predicate<T> match);
// Summary:
// Searches for an element that matches the conditions defined by the specified
// predicate, and returns the first occurrence within the entire
// System.Collections.Generic.List<T>.
//
// Parameters:
// match:
// The System.Predicate<T> delegate that defines the conditions of the element
// to search for.
// (...)
Is it possible to rewrite this method to take a lambda expression as a parameter, and if so, how?
The method can already accept a lambda expression as a parameter, if you want to pass one to it.
The method simply indicates that it accepts a delegate. There are several ways of defining a delegate:
A lambda (Find(a => true))
An anonymous delegate (what you used in your example)
A method group Find(someNamedMethod)
Reflection (Find((Predicate<Whatever>)Delegate.CreateDelegate(typeof(SomeClass), someMethodInfo)))
No need to re-write the method, you can use a lambda already, as below:
Method.Find(x => x.Id == _departmentId );
The code you provide is an anonymous delegate
Method.Find(delegate(Department depts) {
return depts.Id == _departmentId; });
a lambda is an anonymous function.
Related
I have a expression getter like that:
var expression = () => SomeInstance.Nr;
It is passed into a method:
public void AddExpression<T>(Expression<Func<T>> func)
Now I would like to convert that generic expression to
Expression<Func<object>>
I'm not quite sure if I can even do that. I tried something like this:
var converted = Expression.Convert(func, typeof(object));
var objectExpression = Expression.Lambda<Func<object>>(Expression.Call(converted.Method), func.Parameters);
But when I call
var number = objectExpression.Compile()();
It won't return the property value.
The code can be tested here:
http://volatileread.com/utilitylibrary/snippetcompiler?id=25062
Update:
It seems that the invoke is wrapped a second time:
var converted = Expression.Convert(func, typeof(object));
var objectExpression = Expression.Lambda<Func<object>>(Expression.Call(converted.Method), func.Parameters);
var anotherDelegate = objectExpression.Compile().Invoke(); // would have expected the value here
var value = ((Delegate)anotherDelegate).DynamicInvoke(); // this now does return the value
Don't use Expression.Call on delegates - that's only there to call methods. Instead, you want to use Expression.Invoke, which is specifically there to invoke delegates. Also, the key to doing expression trees is wrapping - invoke the inner delegate, convert the result, and wrap this in a lambda:
Expression<Func<int>> inputExpression = () => 42;
var newLambda =
Expression.Lambda<Func<object>>
(
Expression.Convert
(
Expression.Invoke(inputExpression),
typeof(object)
)
);
Console.WriteLine(newLambda.Compile()()); // Prints 42.
newLambda is Expression<Func<object>> and invoking it gives you 42, as you'd expect.
And of course, this makes it rather easy to make this an extension method (although you probably want to use templates to generate all the different Func<...> overloads if you need them).
Do note that this is only going to work if whatever LINQ provider you're using actually supports Invoke - in this case, it's not a problem because the lambda compiler can handle it, but if you need to use something like this with e.g. EntityFramework, you'll need to take a slightly different approach - you'll need to unwrap the inner lambda, convert the body of the inner lambda, and then wrap it again in another lambda. For a parameter-less expression, this is rather easy:
Expression<Func<int>> inputExpression = () => 42;
var newLambda =
Expression.Lambda<Func<object>>
(
Expression.Convert(inputExpression.Body, typeof(object))
);
Console.WriteLine(newLambda.Compile()()); // Prints 42.
Also, for completeness, note that this only works if the inner expression is really a constant expression, and not a quote - but if you needed quoted nested expressions, you probably wouldn't be asking this question :D
I have a helper method which gets the name of a property defined by a lambda which works as below:
ExpressionUtil.GetName((Thing t) => t.Property); // returns "Property"
I would like to turn this into an extension method so the syntax would be of the form:
((Thing t) => t.Property).GetName(); // wont compile : operator '.' cannot be applies to operand of type 'lambda expression'
However I cant seem to do this as ((Thing t) => t.Property) is a lambda (not an expression or Func yet). Is there any way to write an extension method which applies directly to a lambda? If not why is this a bad thing to do?
You can't do that, because a lambda expression has no type by itself; its type is determined by the context (e.g. if you assign it to a delegate variable or pass it as an argument to a method).
Since ((Thing t) => t.Property) doesn't have a type, you can't call an extension method on it, because the compiler doesn't know which extension methods are valid candidates.
You can, however, declare a variable and call the extension method on it:
Func<Thing, OtherThing> func = t => t.Property;
string name = func.GetName();
you may create an extension method on an Action at the low cost of having a introducing instantiation.
I sometimes use it and the code is readable.
The reason this code exists is less elegant, a rotten NAS :-[
new Action(() =>
{
if (File.Exists(newFullPath))
File.Delete(newFullPath);
File.Move(oldFullPath, newFullPath);
})
.Try(attemps: 2, exceptionValidator: (exception, attempt, attempts) =>
{
var throwIt = (attempt == attempts);
if (!throwIt)
Thread.Sleep(500);
// .. tracing ./. throw
return (throwIt);
});
Just in case ... even if post not young.
I am looking at the code from here
/// <summary>
/// Returns the command that, when invoked, attempts
/// to remove this workspace from the user interface.
/// </summary>
public ICommand CloseCommand
{
get
{
if (_closeCommand == null)
_closeCommand = new RelayCommand(param => this.OnRequestClose());
return _closeCommand;
}
}
what does param in param => this.OnRequestClose() refer to?
RelayCommand is presumably a delegate-type that accepts a single parameter, or a type that itself takes such a delegate-type in the constructor. You are declaring an anonymous method, saying simply "when invoked, we'll take the incoming value (but then not use it), and call OnRequestClose. You could also have (maybe clearer):
_closeCommand = new RelayCommand(delegate { this.OnRequestClose(); });
It is probably clearer in other uses where it is used, for example:
var ordered = qry.OrderBy(item => item.SomeValue);
where the lambda is "given an item, obtain the item's SomeValue". In your case the lambda is "given param, ignore param and call OnRequestClose()"
param => this.OnRequestClose() is lambda
Func<sometype_that_param_is,sometype_that_OnRequestClose_Is>
or
Action
I'm not sure which
So it's just an expression for a func that is called by something, that will pass an argument which will be 'param' an then not used
Nothing. The line defines a lambda expression representing a function. That function have a signature like: Foo(T param) where T will be a specific type infered by the compiler based on the type of the argument of the construtor being called.
param is the only parameter of your lambda expression ( param=>this.OnRequestClose() )
As you are instantiating an ICommand object, param would probably contain the parameter passed to this ICommand from the UI. In your case, the parameter is not used in the command (it does not appear on the right side of the lambda expression).
I was going through Jeffrey Palermo's book and came across this syntax.
private void InitializeRepositories()
{
Func<IVisitorRepository> builder = () => new VisitorRepository();
VisitorRepositoryFactory.RepositoryBuilder = builder;
}
What does it mean?
() => indicates a lambda expression that takes no arguments.
In general, it means a function with no arguments.
In this particular example, it creates an anonymous function with no arguments that returns a new VisitorRepository(); object every time.
Func<IVisitorRepository> stands for a delegate which takes no arguments and returns a IVisitorRepository. The creation of that delegate is a lambda function:
() //means no parameters
=> new VisitorRepository()// means it returns a new VisitorRepository
() is the place where you place your variables
Example a common event handled would look like (sender, args)
=> // means throw these parameter into this method
after => you can either drop a one line execution thing like new VisitorRepositor()
OR
you can place a whole function like
Func<IRepository> = (sender, args) =>
{
var myObject = (SomeObject)sender;
return new VisitorReposiroty { id = myObject.SomeId };
}
As other stated it's lambda expression and it really clears your code from method or function that handle a specific event.
Once you read them good it's really damn useful.
The () => syntax is a lambda expression. Lambdas were introduced in C# 3.0 and are used to define an anonymous method for a delegate.
The delegate is defined using the generic Func. So in this case the signature for the delegate is: no input parameters and one output parameter of type IVisitorRepository.
So on the left side of the => lambda array are the names of the input parameters. In case of no input parameters just write (). On the rightside of the => lambda is the code to return the output parameter, in this example: new VisitorRepository().
I suggest read more about lambda expressions in C# to fully understand this code. There is also a generic delegate involved, so you need understanding of Generics and Delegates as well.
Func is a delegate without parmeter and with an IVisitorRepository return value.
() => is a lambda expression creating an anonymous method.
new VisitorRepository() is the content of this anonymous method.
so this line is creating a delegate which is pointing to a anonymous method, which is returning an instance of VisitorRepository.
Func<IVisitorRepository> builder = () => new VisitorRepository()
In the next line, you set the value of a static property to this just created delegate.
VisitorRepositoryFactory.RepositoryBuilder = builder;
After this you can use the property to call the anonymous method, which is creating a new instance of VisitorRepository.
IVisitorRepository repository = VisitorRepositoryFactory.RepositoryBuilder();
In this case, repository will be an instance of VisitorRepository.
It means a function takes no parameters, like:
delegate() {//}
I have a class that builds a url with query string parameters and so on. The class has a method: Url() which returns the complete url composed from the class properties and another method: UrlNew() which allows passing a predicate as parameter for the replacement of the value of one of the properties and THEN Returns the modified URL. Now, I need to modify this function to use TWO parameters, both predicates. How do I do that? I tried modifying the method's parameters as a List of predicates but I probably am not doing something right:
My OLD UrlNew() method looked like this:
public static string Url() (Action<LGUrlBuilder> predicate)
{
var instance = new LGUrlBuilder();
if (predicate != null) predicate(instance);
return instance.BuildUrl();
}
My NEW UrlNew() method looks like this:
public static string UrlNew(List<Action<LGUrlBuilder>> predicateList)
{
var instance = new LGUrlBuilder();
if (predicateList != null && predicateList.Count > 0)
{
foreach (Action<LGUrlBuilder> predicate in predicateList)
{
if (predicate != null) predicate(instance);
}
}
return instance.BuildUrl();
}
This compiles just fine but when I run it, using it in ASPX gives me this error:
CS1660: Cannot convert lambda expression to type 'System.Collections.Generic.List<System.Action<public_site.Library.LG.LGUrlBuilder>>' because it is not a delegate type
I am a C# beginner and I am sure I am doing something completely wrong. Any advice would help. Thanks!
Don't modify the function itself. Modify the method call like this:
UrlNew(x => { func1(x); func2(x); });
But if you really want to take arbitrary number of delegate instances as arguments, try modifying it like:
public static void UrlNew(params Action<LGUrlBuilder>[] list) {
// ... do what you're already doing in the second snippet ...
}
You can call it like:
UrlNew(x => firstthing(), x => secondthing(x), thirdthing);
Side note: An Action<T> is not called a predicate. A predicate returns a boolean value.
How about using the overloaded Action<T1,T2> delegate which accepts 2 parameters.
If you are looking to use a predicate instead which expects a boolean return value then use Func<T1,T2,bool> instead.