Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与.Net 3.5中的表达式.Assign等效?_C#_.net 3.5_.net 4.0_Expression Trees - Fatal编程技术网

C# 与.Net 3.5中的表达式.Assign等效?

C# 与.Net 3.5中的表达式.Assign等效?,c#,.net-3.5,.net-4.0,expression-trees,C#,.net 3.5,.net 4.0,Expression Trees,在.Net 4.0中,Microsoft添加了Expression.Assign。不过,我还是坚持使用3.5。我正试图想出一些方法来编写一个可以设置object属性的方法,但到目前为止,我运气不太好。我可以这样做: public void Assign(object instance, PropertyInfo pi, object value) { pi.SetValue(instance, value, null); } 但是我想避免使用反射的开销!属性不能与ref一起使用。这可能

在.Net 4.0中,Microsoft添加了Expression.Assign。不过,我还是坚持使用3.5。我正试图想出一些方法来编写一个可以设置object属性的方法,但到目前为止,我运气不太好。我可以这样做:

public void Assign(object instance, PropertyInfo pi, object value)
{
    pi.SetValue(instance, value, null);
}

但是我想避免使用反射的开销!属性不能与
ref
一起使用。这可能吗?

因为您的目标是避免反射的开销,但要处理表达式树,所以我假设您正在尝试将表达式编译到委托以设置属性

所有属性都只是幕后的get和set方法。可以调用这些函数,这可以在.NET 3.5表达式树中使用
expression.Call
实现。例如:

class Test{ public int X {get;set;} }

//...elsewhere
var xPropSetter = typeof(Test)
    .GetProperty("X",BindingFlags.Instance|BindingFlags.Public)
    .GetSetMethod();
var newValPar=Expression.Parameter(typeof(int));
var objectPar=Expression.Parameter(typeof(Test));
var callExpr=Expression.Call(objectPar, xPropSetter, newValPar);
var setterAction = (Action<Test,int>)
    Expression.Lambda(callExpr, objectPar, newValPar).Compile();
Test val = new Test();
Console.WriteLine(val.X);//0
setterLambda(val,42);
Console.WriteLine(val.X);//42
类测试{public int X{get;set;}
//……其他地方
var xPropSetter=typeof(测试)
.GetProperty(“X”,BindingFlags.Instance | BindingFlags.Public)
.GetSetMethod();
var newValPar=Expression.Parameter(typeof(int));
var objectPar=Expression.Parameter(typeof(Test));
var callExpr=Expression.Call(objectPar、xPropSetter、newValPar);
var settraction=(操作)
表达式.Lambda(callExpr、objectPar、newValPar).Compile();
测试值=新测试();
控制台写入线(val.X)//0
setterLambda(val,42岁);
控制台写入线(val.X)//42
请注意,如果您只希望委托设置一个值,则也可以创建委托,而无需使用表达式树:

var setterAction = (Action<Test,int>)
    Delegate.CreateDelegate(typeof(Action<Test,int>), xPropSetter);
var settraction=(操作)
CreateDelegate(typeof(Action),xPropSetter);

你能举一个你想要实现的例子吗?你知道替换
表达式的方法吗。赋值是指当你需要给你的
Lambda
ref
out
参数赋值时的情况?我找不到这样做的方法。我想那是不可能的。但是,作为一种解决方法,您可以创建助手方法,例如
static void SetRef(ref T reference,T val){reference=val;}
,并简单地调用它。它可能会稍微慢一点,但您可能会幸运地发现jit内联它-无论如何,它是内联的完美候选。。。