分享

CodeGo.net>如何使用反射创建一个通用对象

 印度阿三17 2019-11-01

首先让我说,我要做的是获取通用类中的属性值,该类可以被继承自该类的类覆盖.在基类中将其视为默认值,该类的继承者可以重写以设置自己的默认值.

我尝试使用System.Reflection.FieldInfo.GetValue直接在类型上使用反射,但这不适用于具有泛型类型的类.因此,我认为我需要实例化该类以了解其值.

我通过读取垃圾箱中的Dll并使用Reflection查找从我的接口继承的类型来检索“类型”.

我正在使用.NET 4.5

这是文档,似乎可以准确解释我需要做什么
http://msdn.microsoft.com/en-us/library/b8ytshk6.aspx

在本文档中,我可以看到的唯一区别是我们如何获取类型,我在bin中查找了类型,它们简称为typeof(),由于类型非常复杂,看来这可能是不匹配的,但我看不到缺少什么(如果有的话)

foreach (var item in types)
{
    var ts = item.GetField("DefaultTimeToExpire");
    Type[] typeArguments = item.GetGenericArguments();
    if (ts != null)
    {
        var t = item.MakeGenericType(typeArguments);
        var obj = Activator.CreateInstance(t);
        var timespan = obj.DefaultTimeToExpire;
        subscriberInfos.Add(new Tuple<string, Type, TimeSpan>(item.Name, item, timespan));
    }
}

我正在调用GetField来查找具有字段“ DefaultTimeToExpire”的项目,到目前为止,这部分很好地找到了我需要的类型.
接下来,我调用GetGenericArguments,它返回Arguments类型的期望数组.
然后我叫MakeGenericType
最后创建实例wich给我错误消息

“因为Type.ContainsGenericParameters为true,所以无法创建BusinessLogic.TestSubscriberXXX`1 [Message]的实例.”

这看起来完全像我应该做的.
谢谢

解决方法:

为了实例化泛型类型,您需要知道应替换其类型参数的实际值(类型). GetGenericArguments()方法是一种反射形式,它仅为您提供类型参数,而不是其实际值.这些值取决于您…这是泛型的全部要点.

如果项目是类似List< T>的类型,然后item.GetGenericArguments()将返回一个数组,该数组包含一个代表类型参数T的假“ type”(其IsGenericParameter属性设置为true).因此,将该参数类型传递回item.MakeGenericType()会简单地创建另一个与原始类型等效的开放通用类型.要关闭通用类型以便可以实例化它,您需要提供一个实际的(非参数)类型参数,例如int.

例如,typeof(List<>).MakeGenericType(typeof(int))将返回typeof(List< int>),而typeof(List<> .MakeGenericType(typeof(List<>)).GetGenericArguments() )将再次简单地返回typeof(List<>).这就是您的代码中正在发生的事情.

很抱歉,如果这有点不透明,我不知道该怎么解释.底线是像List< T>这样的类型.仅在您要替换T的类型时才有用.

来源:https://www./content-4-540101.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多