Lambda Function Using Unknown Parameter - c#

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

Related

Build a compiled delegate corresponding to Enumerable.Cast<T>?

This is very tricky and I'm stuck at the step calling the generic method (MethodInfo) which is returned by another MethodCallExpression (by using MakeGenericMethod) right inside the expression tree context.
Technically the compiled delegate I want looks like this:
Func<IEnumerable, Type, IEnumerable> cast;
So instead of using items.Cast<T>() I can call my compiled delegate like cast(items, typeof(T)).
If using reflection every time calling cast, it would be easy but here I would like to build a compiled delegate based on Expression tree. Here is my code:
public static class EnumerableExtensions {
static readonly Func<IEnumerable, IEnumerable<object>> _enumerableCast = Enumerable.Cast<object>;
static readonly Lazy<MethodInfo> _enumerableCastDefLazy = new Lazy<MethodInfo>(() => _enumerableCast.Method.GetGenericMethodDefinition());
static MethodInfo _enumerableCastDef => _enumerableCastDefLazy.Value;
static Func<Type[], MethodInfo> _makeGenericMethod = _enumerableCastDef.MakeGenericMethod;
static readonly Lazy<Func<IEnumerable, Type, IEnumerable>> _enumerableCompiledCastLazy =
new Lazy<Func<IEnumerable, Type, IEnumerable>>(() => {
var itemsParam = Expression.Parameter(typeof(IEnumerable));
var castTypeParam = Expression.Parameter(typeof(Type));
var castTypeParams = Expression.NewArrayInit(typeof(Type), castTypeParam);
var castMethod = Expression.Call(Expression.Constant(_enumerableCastDef),_makeGenericMethod.Method, castTypeParams);
//here we need to call on castMethod (a static method)
//but the Expression.Call requires a MethodInfo, not an Expression returning MethodInfo
var cast = Expression.Call(..., itemsParam);//<--------- I'm stuck here
return Expression.Lambda<Func<IEnumerable, Type, IEnumerable>>(cast, itemsParam, castTypeParam).Compile();
});
public static Func<IEnumerable, Type, IEnumerable> EnumerableCompiledCast => _enumerableCompiledCastLazy.Value;
public static IEnumerable Cast(this IEnumerable items, Type type){
return EnumerableCompiledCast(items, type);
}
}
So as you can see it's really a dead stuck, never encountered such an issue like this before. I know I can work-around it by invoking the castMethod (as a MethodCallExpression). That way I need to obtain the Invoke method of MethodInfo and use Expression.Call to call that method on the instance castMethod. But wait, if so we still use Method.Invoke as we use Reflection to write code usually without compiling it? I really believe in some hidden magic of Expression.Call which does something different (better and faster) than the MethodInfo.Invoke.
What you're trying to do is completely pointless, and very unlike Enumerable.Cast, which actually does something useful.
Let's take a look at the latter's definition:
IEnumerable<T> Cast<T>(this IEnumerable source);
This takes an untyped IEnumerable and returns a typed IEnumerable<T> based on the generic argument given to the function. You can then use the elements inside the enumerable with the proper type directly, including value types.
Now let's look at your function definition:
IEnumerable Cast(this IEnumerable items, Type type);
This takes an untyped enumerable and returns also an untyped enumerable. What it does inside isn't important, because even if it worked as you want, what you get out of this is still an enumerable of plain objects, so to use these values you still need to cast these things correctly (and unbox the boxed value types). You achieved nothing at all, you already had such a collection -- the thing you passed to your function in the first place.
Even if you make the cast work using a cache of compiled expressions, one per type, which isn't hard to do, the output is still cast back to object by your very return type.

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.

Extension method on lambda expression

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.

Property Lambda expression gets an additional Convert(p=>p.Property)

I have a problem where in some cases (appears to be where property type is bool) a lambda expression used to refer to a property. I use this to get its name; the problem is sometime the expression is getting modified to have an additional Convert() function.
e.g.
GetPropertyName<TSource>(Expression<Func<TSource, object>> propertyLambda) {...}
var str = GetPropertyName<MyObject>(o=>o.MyBooleanProperty);
What's happening it that the propertyLambda looks like Convert(o.MyBooleanProperty) and not o.MyBooleanProperty that i'd expect.
The Convert is added, because o.MyBooleanProperty is a bool, but the result has to be an object. If you made your method generic both in the source object type and the result type, then there would be no Convert:
GetPropertyName<TSource, TResult>(Expression<Func<TSource, TResult>> propertyLambda)
Unfortunately this means you have to specify TResult explicitly:
GetPropertyName<MyObject, bool>(o => o.MyBooleanProperty)
If you don't want to do that, you would have to find some way to infer MyObject, or avoid needing it.
For example, if the current object is MyObject (and you're in an instance method), you could change your code to take Func<TResult>:
GetPropertyName(() => this.MyBooleanProperty)
Or you could include another parameter of type TSource that will help you infer the type:
GetPropertyName(myObject, o => o.MyBooleanProperty)

C#/Lambda: What does param in the following refer to?

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).

Categories

Resources