如何通过反射设置作为通用接口的字段的值?

我希望能够使用反射来获取类的成员,例如,IList 类型,并且我想为它创建一个委托,以便我为反射支付更少的费用。所有这一切,为了在晚些时候,我能够通过传递我的实例和一个新的列表来呼叫代表。每当我尝试这样做时,C#都会给我无效的强制转换异常。我是否遗漏了泛型的愚蠢之处?


我尝试过使用没有泛型的界面字段,这些字段似乎工作得很好。我似乎只在使用泛型时遇到问题。我还尝试使用Convert.ChangeType将我的输入转换为所需的类型,并且我收到了有关List的错误<>没有实现IConvertible。如果我可以使用反射从具体的List<>类型设置一个值<>我将很高兴:)


using System;

using System.Collections.Generic;

using System.Linq.Expressions;

using System.Reflection;


public class MyObject

{

    public IList<int> MyField;

}


public class ReflectionPerfTesting

{


    public void Run()

    {

        var testObject = new MyObject();

        var field = testObject.GetType().GetField("MyField", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

        InvokeUsingReflection(field, testObject);

    }


    private void InvokeUsingReflection(FieldInfo fieldInfo, object testObject)

    {

        var fieldType = fieldInfo.FieldType;

        var sourceType = fieldInfo.DeclaringType;


        // ZAS: create value parameter

        var valueParam = Expression.Parameter(fieldType);


        // ZAS: create targetParameter

        var sourceParam = Expression.Parameter(sourceType);


        var field = Expression.Field(sourceParam, fieldInfo);

        var returnExpression = (Expression)Expression.Assign(field, valueParam);

        if (!fieldType.IsClass)

        {

            returnExpression = Expression.Convert(returnExpression, fieldType);

        }


    }


}

预期的结果是,我能够将“setter”缓存到属性中,并支持设置任何类型的值,包括泛型和接口。我目前的结果是,设置任何类型的值都有效,除非有泛型...所以我一定是做错了什么。


蛊毒传说
浏览 82回答 1
1回答

莫回无

您的 lambda 调用是错误的。您必须在 lambda 对象上调用该方法,该对象传递目标以及参数。Invoke如果修复调用,您将获得所需的结果:testObject.Dump();var list = new List<int>();lambdaInvokeMethod.Invoke(lambda, new object[] { testObject, list });testObject.Dump();Dumping object(MyObject)&nbsp;MyField&nbsp; : nullDumping object(MyObject)&nbsp;MyField&nbsp; : []请参见: https://dotnetfiddle.net/FZN3iX
打开App,查看更多内容
随时随地看视频慕课网APP