为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
蛊毒传说 2022-09-04 16:51:43
我希望能够使用反射来获取类的成员,例如,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”缓存到属性中,并支持设置任何类型的值,包括泛型和接口。我目前的结果是,设置任何类型的值都有效,除非有泛型...所以我一定是做错了什么。
查看完整描述

1 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

您的 lambda 调用是错误的。您必须在 lambda 对象上调用该方法,该对象传递目标以及参数。Invoke


如果修复调用,您将获得所需的结果:


testObject.Dump();


var list = new List<int>();

lambdaInvokeMethod.Invoke(lambda, new object[] { testObject, list });


testObject.Dump();

Dumping object(MyObject)

 MyField  : null

Dumping object(MyObject)

 MyField  : []

请参见: https://dotnetfiddle.net/FZN3iX


查看完整回答
反对 回复 2022-09-04
  • 1 回答
  • 0 关注
  • 76 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信