gpt4 book ai didi

c# - 如何使用反射创建通用对象

转载 作者:行者123 更新时间:2023-11-30 15:37:51 24 4
gpt4 key购买 nike

首先让我说,我想要做的是获取泛型类中属性的值,该类可能会被继承自它的类覆盖。将其视为基类中的默认值,该类的继承者可以重写以设置自己的默认值。

我尝试使用 System.Reflection.FieldInfo.GetValue 直接在类型上使用反射,但这不适用于具有泛型类型的类。所以我认为我需要实例化该类才能看到值是什么。

我通过读取 bin 中的 Dll 并使用反射查找从我的接口(interface)继承的类型来检索“类型”。

我正在使用 .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最后 Create instance 给了我错误信息

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

这看起来正是我应该做的。谢谢

最佳答案

为了实例化泛型类型,您需要知道应该替换其类型参数的实际值(类型)。 GetGenericArguments()方法,作为一种反射形式,只为您提供类型参数,而不是它们的实际值。值由您决定……这就是泛型的全部意义所在。

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

例如,typeof(List<>).MakeGenericType(typeof(int))将返回 typeof(List<int>) , 而 typeof(List<>).MakeGenericType(typeof(List<>).GetGenericArguments())只会返回 typeof(List<>)再次。这就是您的代码中发生的情况。

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

关于c# - 如何使用反射创建通用对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12168536/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com