Extension method on lambda expression - c#

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.

Related

Does `this.SomeMethod` passed as Func argument capture `this`?

If a method asks for some Func:
void Foo(Func<string> stringFactory);
Then passing a lambda referencing this introduces variable capturing:
Foo(() => this.MagicStringProperty); // Captures `this`
Does this happen also when passing an instance method instead of a lambda?
Foo(this.GetMagicString); // Capturing??
string GetMagicString()
{
return "Bar";
}
If so, is this compiled to a similar thing as the lambda version?
If not, how does it manage to pass both the method (which exists somewhere) and the instance (which exists somewhere else)?
this doesn't have to be captured in a closure here. The difference between the calls is that there is a compiler generated method for () => this.MagicStringProperty(). This method simply calls this.GetMagicString().
If you decompile the code you will see that Foo(this.GetMagicString) translates to this.Foo(new Func<string>((object) this, __methodptr(GetMagicString))) and that Foo(() => this.GetMagicString()) translates to this.Foo(new Func<string>((object) this, __methodptr(<.ctor>b__1_0))) where <.ctor>b__1_0 is the compiler generated method that calls this.GetMagicString():
[CompilerGenerated]
private string <.ctor>b__1_0()
{
return this.GetMagicString();
}

Convert generic getter expression to object getter expression

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

How to change delegate expression to lambda?

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.

Lambda Function Using Unknown Parameter

I see PRISM declaring the following constructor, and I don't understand what's that "o" being used with the lambda function that serves as the second parameter when the base constructor is called:
public DelegateCommand(Action<T> executeMethod)
: this(executeMethod, (o)=>true)
{
}
I'd appreciate an explanation.
The constructor which declaration you posted calls another constructor, so to explain it, we should first look at the other constructor’s signature:
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
So the second parameter is a Func<T, bool>. That means it is a function that takes a parameter of type T and returns a boolean.
Now if you look at the lambda that is used:
(o) => true
Lambdas in general have the syntax (parameter-list) => lambda-body, so in this case, the single parameter of the lambda is a variable o (which type is inferred to be T) and the function returns a constant result true.
The purpose of this is to basically make a command that is always executable.
Of course that lambda could look a lot more complicated, so when using the DelegateCommand, you are likely to use more complex and non-constant expressions. For example:
new DelegateCommand(DoSomething, o => o.SomeProperty >= 0 && o.SomeProperty < 10 && o.SomeBoolProperty)
It calls this constructor:
DelegateCommand<T>(Action<T>, Func<T, Boolean>)
Passing a lambda that always returns true as the second parameter

What does this mean in C# or LINQ? - ( () => )

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() {//}

Categories

Resources