По-долу са дадени два метода, които създават делегат за задаване на поле в клас. Единият метод използва генерични лекарства, а другият не. И двата метода връщат делегат и работят добре. Но ако се опитам да използвам делегата, който е създаден в метода CreateDelegate, тогава негенеричният делегат 'del' работи добре. Мога да поставя точка на прекъсване на оператора за връщане и да извикам делегата, като напиша del(222). Но ако се опитам да извикам генеричния делегат 'genericDel', като напиша genericDel(434), той хвърля изключение:
Делегатът „System.Action“ има някои невалидни аргументи
Може ли някой да обясни тази странност.
class test
{
public double fld = 0;
}
public static void Main(string[] args)
{
test tst = new test() { fld = 11 };
Type myType = typeof(test);
// Get the type and fields of FieldInfoClass.
FieldInfo[] myFieldInfo = myType.GetFields(BindingFlags.Instance | BindingFlags.Public);
var a = CreateDelegate<double>(myFieldInfo[0], tst);
var b = CreateDelegate(myFieldInfo[0], tst);
Console.WriteLine(tst.fld);
b(5.0);
Console.WriteLine(tst.fld);
a(6.0);
Console.WriteLine(tst.fld);
}
public static Action<T> CreateDelegate<T>(FieldInfo fieldInfo, object instance)
{
ParameterExpression numParam = Expression.Parameter(typeof(T), "num");
Expression a = Expression.Field(Expression.Constant(instance), fieldInfo);
BinaryExpression assExp = Expression.Assign(a, numParam);
Expression<Action<T>> expTree =
Expression.Lambda<Action<T>>(assExp,
new ParameterExpression[] { numParam });
Action<T> genericDel = expTree.Compile();
//try to invoke the delegate from immediate window by placing a breakpoint on the return below: genericDel(323)
return genericDel;
}
public static Action<double> CreateDelegate(FieldInfo fieldInfo, object instance)
{
ParameterExpression numParam = Expression.Parameter(typeof(double), "num");
Expression a = Expression.Field(Expression.Constant(instance), fieldInfo);
BinaryExpression assExp = Expression.Assign(a, numParam);
Expression<Action<double>> expTree =
Expression.Lambda<Action<double>>(assExp,
new ParameterExpression[] { numParam });
Action<double> del = expTree.Compile();
//try to invoke the delegate from immediate window by placing a breakpoint on the return below: del(977)
return del;
}
a(5.0)
иb(5.0)
и работят правилно. Имайте предвид, че този код е C# 4.0 (Expression.Assign
е въведен там) - person xanatos   schedule 22.10.2011a()
иb()
във вашия код, така че кодът може да се тества директно. - person xanatos   schedule 22.10.2011