이것은 내 간단한 테스트 코드입니다. 2 개체 사이의 필드 할당 링크를 만들고 싶습니다. 필드는 런타임시 setter/getter 메서드의 대리자를 캐싱하여 리플렉션을 사용하여 결정됩니다. 하지만, 어떻게 든 작동하지 않습니다. 할당이 작동하지 않습니다. 어쩌면 나는 어리석은 실수를 저질렀을지도 모른다. 내가 어디가 잘못 됐어?대리인을 사용하는 Field Setter/Getter
public static class AssignmentExpression
{
public static Expression Create(Expression left, Expression right)
{
MethodInfo m = typeof(AssignmentExpression)
.GetMethod("AssignTo", BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(left.Type);
return Expression.Call(null,m,left, right);
}
private static void AssignTo<T>(ref T left, T right)
{
left = right;
}
}
public class FieldLink
{
protected Delegate srcGetter;
protected Delegate dstSetter;
public FieldLink(FieldInfo srcObject, FieldInfo dstObject)
{
this.srcGetter = FieldLink.createGetter(srcObject);
this.dstSetter = FieldLink.createSetter(dstObject);
}
public void update<T>(T dst, T src)
{
this.dstSetter.DynamicInvoke(dst, this.srcGetter.DynamicInvoke(src));
}
protected static Delegate createGetter(FieldInfo field)
{
ParameterExpression objParm = Expression.Parameter(field.DeclaringType, "obj");
Type delegateType = typeof(Func<,>).MakeGenericType(field.DeclaringType, field.FieldType);
MemberExpression fieldExpr = Expression.Field(objParm, field.Name);
LambdaExpression lambda = Expression.Lambda(delegateType, fieldExpr, objParm);
return lambda.Compile();
}
protected static Delegate createSetter(FieldInfo field)
{
ParameterExpression objParm = Expression.Parameter(field.DeclaringType, "obj");
ParameterExpression valueParm = Expression.Parameter(field.FieldType, "value");
Type delegateType = typeof(Action<,>).MakeGenericType(field.DeclaringType, field.FieldType);
MemberExpression memberExpr = Expression.Field(objParm, field.Name);
Expression assignExpr = AssignmentExpression.Create(memberExpr, valueParm);
LambdaExpression lambda = Expression.Lambda(delegateType, assignExpr, objParm, valueParm);
return lambda.Compile();
}
}
public class Test
{
public int fieldInt = 0;
}
public class TestClass
{
public Test a = new Test();
public Test b = new Test();
public void Start()
{
a.fieldInt = 5;
Debug.Log("before a = " + a.fieldInt + " b = " + b.fieldInt);
FieldLink testLink = new FieldLink(this.a.GetType().GetField("fieldInt"),
this.b.GetType().GetField("fieldInt"));
testLink.update(this.b, this.a);
Debug.Log("after a = " + a.fieldInt + " b = " + b.fieldInt);
//here a.fieldInt should be equal to b.fieldInt, but somehow its unchanged!
}
}
이상하게도 내 경우 args를 되 돌린 후에도 값은 동일합니다. btw 내 환경은. 닷넷 3.5 그래서 나는'Expression.Assign'을 가지고 있지 않다. – uray
Ahh, ok - 나는 4.5에서 그것을 실행했다 - 다시 3.5에서 그것을 점검 할 것이다 ... –
... 그것은 여전히 나를 위해 일한다. VS2012, .NET 3.5에서 실행중인 'AssignmentExpression' 클래스 - 둘 다 5로 끝나거나 둘 다 결국 0으로 끝납니다. 매우 이상합니다! –