Why can I not use lambda expression directly in implicit operator? - c#

The following code does not compile in .Net as it throws an error about lambda expressions cannot be converted to delegate of Action directly.
public class Sample {
public static implicit operator Sample(Action action) { return new Sample(); }
}
public static void Main(string[] args) {
Sample y = void () => { };
}
This can be fixed by casting the expression into Action delegate, as follow
Sample y = (Action)(void () => { });
Or it can be fixed by creating an intermediate variable, as follow
var x = void () => { };
Sample y = x;
Question is why does not the compiler recognizes this by default? Why is there has to be an intermediate variable?
How does the signature of the operator needs to be changed to allow lambda expression to be accepted. I do not want to use LambdaExpression or Delegate as the implicit operator.
I would expect the following code to compile Sample y = void () => { };, since introducing the intermediate variable fixed the issue.

Related

Pass a lambda expression as a parameter, then execute that lambda with a parameter

Say I have the following (incorrect) code;
public void Foo()
{
bool retVal = Bar(x => x.Any(y => y.Contains(z)); // Where z is "my variable" (below)
}
public bool Bar(Func<List<MyObject>, bool> pFunc)
{
return pFunc("a variable");
}
How do I pass the lambda expression, written in the call to Bar, so that it is executed in Bar, using an additional variable that only exists in Bar()?
The code does not have to remain this simple.
You can have two inputs in a lambda: (x,z)
public void Foo()
{
bool retVal = Bar((x,z) => x.Any(y => y.Contains(z))); // Where z is "my variable" (below)
}
public bool Bar(List<MyObject> list, Func<List<MyObject>, string, bool> pFunc)
{
return pFunc(list, "a variable");
}
Which means you have to update the Func signature to Func<List<MyObject>, string, bool> as well to reflect (x,z)=>bool
I also updated Bar signature to give the input list because it was missing. Maybe it is a local variable or class member. Anyway you should be able to adapt your code starting from here

Lambda expression "=>"

I'm trying to understand a code but I can't understand what 'p' var is.
public Prediction(Game kkk,bool checkit, params State[] checkStates)
: base(game, p => Manager.method(kkk, p))
{
this.checkit = checkit;
this.checkStates = checkStates;
}
The second class:
public PiratePrediction(Game game, System.Func<Pirate, T> valueExtractor)
{
this.game = game;
this.valueExtractor = valueExtractor;
this.predictedValues = new Dictionary<Pirate, T>();
this.totalPredictions = 0;
this.correctPredictions = 0;
}
found the class you're using on https://github.com/YoavKa/Skillz2016/blob/f23d25eed4baa9786cf517583ee867075a2f0505/API/Prediction/PiratePrediction.cs
the valueExtractor lambda is used from Update, and p comes from the keys of predictedValues dictionary.
public virtual void Update()
{
foreach (var pair in this.predictedValues)
{
if (pair.Key.State != PirateState.Lost && !EqualityComparer<T>.Default.Equals(pair.Value, default(T)))
{
this.totalPredictions++;
if (this.valueExtractor(pair.Key).Equals(pair.Value))
this.correctPredictions++;
}
}
this.predictedValues.Clear();
}
the p comes from the call to Predict method of PiratePrediction class. Because it's added to the predictedValues array.
public T Predict(Pirate p)
{
if (this.predictedValues.ContainsKey(p))
return this.predictedValues[p];
T predictedValue = this.predict(p);
if (EqualityComparer<T>.Default.Equals(predictedValue, default(T)))
return default(T);
this.predictedValues.Add(p, predictedValue);
return predictedValue;
}
p is a parameter being passed into your method. A Func<T, TOut> is a delegate, meaning a method signature.
Consider the following:
private class DisplayClass
{
public readonly Game kkk;
public DisplayyClass(Game kkk) { this.kkk = kkk; }
public T handler(Pirate p) { return Manager.method(kkk, p); }
}
public Prediction(Game kkk,bool checkit, params State[] checkStates)
: base(game, new DisplayClass(kkk).handler)
{
this.checkit= checkit;
this.checkStates = checkStates;
}
This is what the compiler does to your code when interpreting lambdas - it may be a good idea to pass your code through a decompiler to see the exact phrasing.
The p variable, as you can see in the expanded code, is a parameter into the method, and lambdas are just a shorthand way to pass methods which can then be invoked in other code.
// Somewhere in the base class...
void ExtractValue(Pirate p)
{
// ...
T value = this.valueExtractor(p);
// ...
}
When thus invoked, p will be the value passed in by that other code, and by definition of Func<Pirate, T>, will be of type Pirate.
Keep in mind that the code you're passing a lambda to can invoke the code inside your lambda multiple times, such as is the case with .Select. I suggest not only reading up on lambdas, but also their extensive use in the Linq namespace
A lambda expression is a declaration of an anonymous method. So imagine that this:
p => Manager.method(kkk, p)
is equal to this:
private T SomeMethod<T>(Pirate p)
{
return Manager.method(kkk, p);
}
You wouldn't be able to do the second snippet in your situation, however, because kkk is a local variable from the scope of where the lambda expression was declared, which means that while the lambda can use kkk, an explicit method declaration can't (See Closure). This is just one benefit of lambdas over declared methods.

C# - How to access instances of a particular type that are used in Func<int> delegate

In Factory.Process(..) method, I want get hold of instances of MyClass that are being used in the lambda expression of the Func delegate. But, How?
Can someone help me find a way to do it.
Edit: This is an artificial example that demonstates my need. My intention behind this approach is that, I want to keep track of (or subscribe to) all the MyClass objects that are used in the delegate definition. So that, I can recalculate my total value whenever any MyClass object value is changed. Please suggest as to how to go about to solve this.
Note: Expression tree doesnt seem to help in my case because I cant modify my parameter type at this moment and it restricts the usage of my complex function definitions.
public class MyClass
{
public int Value;
public MyClass(int value)
{
Value = value;
}
}
public class TestClass
{
public void TestMethod()
{
var obj1 = new MyClass(10);
var obj2 = new MyClass(20);
Factory.Process(() => obj1.Value + obj2.Value);
}
}
public static class Factory
{
public static void Process(Func<int> function)
{
var total = function.Invoke();
// Here, apart from invoke, I want to access the all the instances of MyClass that are used in 'function'
// but how do I get to obj1 and obj2 objects through the 'function' delegate?
}
}
First of all, if you type an input parameter as just Func<T> it's not an expression, but just a lambda syntax for delegates.
If you want to be able to access the expression and do some reflection and/or analysis, you need to type your parameters as Expression<T>. For example: Expression<Func<int>>. This turns your expression into an expression tree.
Expression trees enable you to access the expression like a data structure. Once you've finished analyzing your expression tree, you can call yourExpression.Compile(), and this will compile your expression tree into a delegate that can be invoked as any other delegate (either named and anonymous ones).
For example, obj1 would be accessed this way:
public class MyClass
{
public int Value { get; set; }
}
static void Main(string[] args)
{
var obj1 = new MyClass { Value = 1 };
var obj2 = new MyClass { Value = 2 };
Expression<Func<int>> expr = () => obj1.Value + obj2.Value;
BinaryExpression binaryExpr = (BinaryExpression)expr.Body;
MemberExpression memberExpr = (MemberExpression)binaryExpr.Left;
MemberExpression fieldExpr = (MemberExpression)memberExpr.Expression;
ConstantExpression constantExpr = (ConstantExpression)fieldExpr.Expression;
dynamic value = constantExpr.Value;
MyClass some = value.obj1;
}
Update
OP said in some comment:
unfortunately, changing from parameter Func to
Expression> doesnt seem to work well in my situation because,
expression tree is restricting my function delegate definition from
using assignment operators and statement body.
My answer to this is you want an unexisting universal solution, because any other solution might compromise maintainability.
Maybe there's an alternative that will allow you to stay with delegates instead of expression trees: a delegate with an out parameter which would contain a collection of objects involved in there...
Since standard BCL Func delegates don't come with output parameters, you can declare your own Func delegate as follows:
public delegate TResult Func<out T>(out IDictionary<string, object> objects);
...and your delegate should set the so-called out parameter:
using System;
using System.Collections.Generic;
public class Program
{
public class MyClass
{
public int Value { get; set; }
}
public delegate void Func<out T>(out IDictionary<string, object> objects);
public static void Main()
{
Func<int> someFunc = (out IDictionary<string, object> objects) =>
{
var obj1 = new MyClass { Value = 1 };
var obj2 = new MyClass { Value = 2 };
int result = obj1.Value + obj2.Value;
objects = new Dictionary<string, object> { { "obj1", obj1 }, { "obj2", obj2 } };
};
IDictionary<string, object> objectsInFunc;
someFunc(out objectsInFunc);
}
}
As written, it cannot be done, because you're trying to access information about the exact code and would thus need to examine the incoming IL (since the actual C# code is gone after compilation).
However, it WOULD be possible using the metacode libraries of System.Linq.Expression namespace, but only if you swap out Func<int> for Expression<Func<int>>. With this, you would then be able to walk the expressions tree created by your lambda call. Using an Expression in place of another delegate type also tells the compiler to make an expression tree, rather than actually compiling the code, so this won't work if you pass a direct method or try to examine non-expression tree objects the same way.
You can if you change the parameter type of Process to Expression<Func<int>> expr:
public static void Process(Expression<Func<int>> expr)
{
Func<int> function = expr.Compile();
var total = function();
Expression left = ((BinaryExpression)expr.Body).Left;
Expression leftObjExpr = ((MemberExpression)left).Expression;
Expression<Func<MyClass>> leftLambda =
Expression.Lambda<Func<MyClass>>(leftObjExpr);
Func<MyClass> leftFunc = leftLambda.Compile();
MyClass obj1 = leftFunc();
int value = obj1.Value; // ==> 10
// Same with right operand...
}
Note that you can still invoke the function; you just have to compile the lambda expression to get a callable function.
However, this will only work with a binary expression. If you want to parse all kinds of expressions, this becomes quite complicated. You best solve this problem with the Visitor pattern.

Making a value type behave as a reference type using Expression<Func<T>>

We know that int is a value type and so the following makes sense:
int x = 3;
int y = x;
y = 5;
Console.WriteLine(x); //says 3.
Now, here is a bit of code where we want to for lack of a better term "link" the two variables point to the same memory location.
int x = 3;
var y = MagicUtilClass.linkVariable(() => x);
y.Value = 5;
Console.WriteLine(x) //says 5.
The question is: How does the method linkVariable look like? What would it's return type look like?
Although, I titled the post as making a value type behave as a reference type, the said linkVariable method works for reference types too.., i.e,
Person x = new Person { Name = "Foo" };
var y = MagicUtilClass.linkVariable(() => x);
y.Value = new Person { Name = "Bar" };
Console.WriteLine(x.Name) //says Bar.
I am not sure how to achieve this in C# (not allowed to use unsafe code by the way)?
Appreciate ideas. Thanks.
Here is a full solution:
// Credits to digEmAll for the following code
public delegate void Setter<T>(T newValue);
public delegate T Getter<T>();
public class MagicPointer<T>
{
private Getter<T> getter;
private Setter<T> setter;
public T Value
{
get { return getter(); }
set { setter(value); }
}
public MagicPointer(Getter<T> getter, Setter<T> setter)
{
this.getter = getter;
this.setter = setter;
}
}
// Code starting from here is mine
public static class MagicUtilClass
{
public static MagicPointer<T> LinkVariable<T>(Expression<Func<T>> expression)
{
var memberExpr = expression.Body as MemberExpression;
if (memberExpr == null)
throw new InvalidOperationException("The body of the expression is expected to be a member-access expression.");
var field = memberExpr.Member as FieldInfo;
if (field == null)
throw new InvalidOperationException("The body of the expression is expected to be a member-access expression that accesses a field.");
var constant = memberExpr.Expression as ConstantExpression;
if (constant == null)
throw new InvalidOperationException("The body of the expression is expected to be a member-access expression that accesses a field on a constant expression.");
return new MagicPointer<T>(() => (T) field.GetValue(constant.Value),
x => field.SetValue(constant.Value, x));
}
}
Usage:
int x = 47;
var magic = MagicUtilClass.LinkVariable(() => x);
magic.Value = 48;
Console.WriteLine(x); // Outputs 48
To understand why this solution works, you need to know that the compiler transforms your code quite considerably whenever you use a variable inside a lambda expression (irrespective of whether that lambda expression becomes a delegate or an expression tree). It actually generates a new class containing a field. The variable x is removed and replaced with that field. The Usage example will then look something like this:
CompilerGeneratedClass1 locals = new CompilerGeneratedClass1();
locals.x = 47;
var magic = MagicUtilClass.LinkVariable(() => locals.x);
// etc.
The “field” that the code retrieves is the field containing x, and the “constant” that it retrieves is the locals instance.
You can do something like this:
public delegate void Setter<T>(T newValue);
public delegate T Getter<T>();
public class MagicPointer<T>
{
private Getter<T> getter;
private Setter<T> setter;
public T Value
{
get
{
return getter();
}
set
{
setter(value);
}
}
public MagicPointer(Getter<T> getter, Setter<T> setter)
{
this.getter = getter;
this.setter = setter;
}
}
usage:
int foo = 3;
var pointer = new MagicPointer<int>(() => foo, x => foo = x);
pointer.Value++;
//now foo is 4
Of course this solution doesn't guarantee a strong compile time control, because is up to the coder to write a good getter or setter.
Probably, if you need something like a pointer you should reconsider your design, because likely you can do it in another way in C# :)
Integers in .NET are immutable. I'm not sure what problem you're trying to solve with this issue. Have you considered creating a class which has a property which "wraps" the integer? That class would be a reference types and what you're trying to achieve would not require any "magic" utility classes - just normal C# reference-type behavior.

Is there a difference between return myVar vs. return (myVar)?

I was looking at some example C# code, and noticed that one example wrapped the return in ()'s.
I've always just done:
return myRV;
Is there a difference doing:
return (myRV);
UPDATE: This question was the subject of my blog on 12 April 2010. Thanks for the amusing question!
In practice, there is no difference.
In theory there could be a difference. There are three interesting points in the C# specification where this could present a difference.
First, conversion of anonymous functions to delegate types and expression trees. Consider the following:
Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }
F1 is clearly legal. Is F2? Technically, no. The spec says in section 6.5 that there is a conversion from a lambda expression to a compatible delegate type. Is that a lambda expression? No. It's a parenthesized expression that contains a lambda expression.
The Visual C# compiler makes a small spec violation here and discards the parenthesis for you.
Second:
int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }
F3 is legal. Is F4? No. Section 7.5.3 states that a parenthesized expression may not contain a method group. Again, for your convenience we violate the specification and allow the conversion.
Third:
enum E { None }
E F5() { return 0; }
E F6() { return (0); }
F5 is legal. Is F6? No. The spec states that there is a conversion from the literal zero to any enumerated type. "(0)" is not the literal zero, it is a parenthesis followed by the literal zero, followed by a parenthesis. We violate the specification here and actually allow any compile time constant expression equal to zero, and not just literal zero.
So in every case, we allow you to get away with it, even though technically doing so is illegal.
There are corner cases when presence of parentheses can have effect on the program behavior:
1.
using System;
class A
{
static void Foo(string x, Action<Action> y) { Console.WriteLine(1); }
static void Foo(object x, Func<Func<int>, int> y) { Console.WriteLine(2); }
static void Main()
{
Foo(null, x => x()); // Prints 1
Foo(null, x => (x())); // Prints 2
}
}
2.
using System;
class A
{
public A Select(Func<A, A> f)
{
Console.WriteLine(1);
return new A();
}
public A Where(Func<A, bool> f)
{
return new A();
}
static void Main()
{
object x;
x = from y in new A() where true select (y); // Prints 1
x = from y in new A() where true select y; // Prints nothing
}
}
3.
using System;
class Program
{
static void Main()
{
Bar(x => (x).Foo(), ""); // Prints 1
Bar(x => ((x).Foo)(), ""); // Prints 2
}
static void Bar(Action<C<int>> x, string y) { Console.WriteLine(1); }
static void Bar(Action<C<Action>> x, object y) { Console.WriteLine(2); }
}
static class B
{
public static void Foo(this object x) { }
}
class C<T>
{
public T Foo;
}
Hope you will never see this in practice.
No, there is no difference other than syntactical.
A good way to answer questions like this is to use Reflector and see what IL gets generated. You can learn a lot about compiler optimizations and such by decompiling assemblies.

Categories

Resources