I want to get the Expression of the Expression-bodied Property. I have no idea how to do that;/ Here is the simple code snippet:
class TestTest
{
public int A { get; set; } = 5;
public int AX5 => A * 5;
}
public class Program
{
public static void Main()
{
var testObj = new TestTest();
Expression<Func<TestTest, int>> expr = (t) => t.AX5;
}
}
This code works, but AX5 is not marked as Expression, it is the simple Int32 property.
This is the result i want to get from the property:
The so called "Expression-Body" is just sugar to shorten function and property declarations. It does not have anything to do with the Expression<> type.
The 'expression-bodied' property in your class is equivalent to:
public int AX5
{
get { return A * 5; }
}
However, if you really wanted to capture this readonly property, you would have to retrieve the compiler generated get-method via reflection and then add an extra parameter to the Func<int> in order to pass the object-instance the property belongs to -> Func<TestTest, int>.
Here's an example:
class TestTest
{
public int A { get; set; } = 5;
public int AX5 => A * 5;
}
var f = typeof(TestTest).GetMethod("get_AX5")
.CreateDelegate(typeof(Func<TestTest, int>))
as Func<TestTest, int>;
Expression<Func<TestTest, int>> exp = instance => f(instance);
Note this is adding an additional function call to capture the new lambda-expression. Converting the get-method to an expression otherwise would get quite complicated.
This is not very useful though, usually you want to work the other way around and build Expression Trees to compile them to delegates later on.
Checkout the docs for Expression Trees for further information.
Related
I've been trying to implement raw lambda calculus on C# but I am having some troubles implementing it, as in the end, I am always asked for objects.
I would like something that would allow me, for instance, to define a few basic logical combinators, such as
I = Lambda x. x
M = Lambda x. x(x)
but C# seems to run on the assumption that it will get an object in the end. I've tried to define them in various ways, such as
using lambda = Func<Object, Object>;
using lambda = Func<Func<Object, Object>, Func<Object, Object>>;
using lambda = Func<Func, Func>;
and so on, but either those do not obey the syntax or are incompatible with
lambda I = x => x;
lambda M = x => x(x);
I tried using the delegate
public delegate object lambda(Object o);
static object i(object o)
{
return o;
}
static object m(object o)
{
return ((lambda)o)(o);
}
But in the end, any actual use of those functions will still require an argument at the end of the line, and a dummy argument like
m(m(i('')));
will simply lead to a cast error during execution.
Is there a way to implement typeless lambda calculus natively, or do I have to go back to string processing?
For an example of execution of the program, it would look something like this. For the following functions :
lambda i(lambda x)
{
print("i");
return x;
}
lambda m(lambda x)
{
print("m");
return x(x);
}
The execution of (m(m))(i) should be something like m(m) is evaluated, returning m(m) after printing "m", which gives us back the original (m(m))(i), which will then print an infinite amount of "m" (this is the simplest infinite loop with logical combinators, although this will involve some trampolining later on to avoid blowing the stack).
Rather than encoding a lambda expression as Func<,> (which is probably not a good match for untyped lambda calculus), you should encode it as an abstract syntax tree. Something like this:
public class LambdaAbstraction: ILambdaExpression {
public LambdaVariable Variable { get; set; }
public ILambdaExpression Body { get; set; }
}
public class LambdaApplication: ILambdaExpression {
public ILambdaExpression Function { get; set; }
public ILambdaExpression Argument { get; set; }
}
public class LambdaVariable: ILambdaExpression {
public string Name { get; set; }
}
For example, M would be
ILambdaExpression M = new LambdaAbstraction {
Variable = new LambdaVariable { Name = "x" },
Body = new LambdaApplication {
Function = new LambdaVariable { Name = "x" },
Argument = new LambdaVariable { Name = "x" }
}
}
Then it's quite straightforward to implement recursive methods for alpha renaming and beta reductions on this data structure.
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.
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.
I am trying to make dynamic expression and assign lambda to it. As a result, I got exception:
System.ArgumentException: Expression of type 'Test.ItsTrue' cannot be used for assignment to type 'System.Linq.Expressions.Expression`1[Test.ItsTrue]'
What is wrong?
public delegate bool ItsTrue();
public class Sample
{
public Expression<ItsTrue> ItsTrue { get; set; }
}
[TestClass]
public class MyTest
{
[TestMethod]
public void TestPropertySetWithExpressionOfDelegate()
{
Expression<ItsTrue> itsTrue = () => true;
// this works at compile time
new Sample().ItsTrue = itsTrue;
// this does not work ad runtime
var new_ = Expression.New(typeof (Sample));
var result = Expression.Assign(
Expression.Property(new_, typeof (Sample).GetProperties()[0]),
itsTrue);
}
}
The second argument of Expression.Assign is the expression representing the value to assign. So currently you're effectively trying to assign an ItsTrue to the property. You need to wrap it so that it's an expression returning the value itsTrue... either via Expression.Quote or Expression.Constant. For example:
var result = Expression.Assign(
Expression.Property(new_, typeof (Sample).GetProperties()[0]),
Expression.Constant(itsTrue, typeof(Expression<ItsTrue>)));
Alternatively, you might want Expression.Quote - it really depends on what you're trying to achieve.
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.