在运行时使用反射构造泛型的具体类型的实例

发布于 2024-12-10 16:23:15 字数 354 浏览 0 评论 0原文

考虑以下类:

public class GenericClass<T>
{
   public T Argument;                
}

第二个类引用并使用 GenericClass:

public class ClientClass
{
    GenericClass<T> genclass = new GenericClass<T>();
}

我的问题是我在编译时不知道 T 的类型。我在运行时使用反射来获取 T 的类型。在实例化 GenericClass 时是否可以以某种方式使用参数化表达式?

Consider the following class:

public class GenericClass<T>
{
   public T Argument;                
}

And a second class that references and uses the GenericClass:

public class ClientClass
{
    GenericClass<T> genclass = new GenericClass<T>();
}

My problem is that I don't know the type of T at compile time. I am using reflection during runtime to obtain the type of T. Is it possible somehow to use a parametrized expression while instantiating the GenericClass?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我鬧 2024-12-17 16:23:15

是的,但是您必须使用反射来构建您正在寻找的实际类型。

您首先需要使用 typeof 运算符获取开放泛型:

var openType = typeof(GenericClass<>);

接下来,您需要构建您想要的特定泛型。 假设您想要的类型 T 存储在变量中,type

var closedType = openType.MakeGenericType(type);

最后,使用反射创建该类型的实例。

object instance = Activator.CreateInstance(closedType);

正如 xanatos 中所述但是,您应该知道这会产生 object 类型的成员。为了能够在不反射的情况下操作对象,您有两种选择。

  1. 您可以创建一个父类 GenericClassGenericClass 派生自该父类,并在其中包含所有通用的方法。 (即 GenericClass 包含不需要使用 T 的成员。
  2. 正如 Ingenu 在问题评论中提到的,您可以创建一个接口 IInterface,然后添加对 T 的限制,where T : IInterface 然后,您可以将 instance 转换为 GenericClass。 ; 和显然,在这种情况下,type 必须实现 IInterface

您当然也可以保留 object 引用并使用它进行操作 。仅反射,或使用动态来后期绑定任何方法调用——但是,这在幕后使用了反射。

Yes, but you'll have to use reflection to build the actual type for which you're looking.

You first need to get the open generic, by using the typeof operator:

var openType = typeof(GenericClass<>);

Next, you need to build the specific generic you want. Say your desired type T is stored in a variable, type:

var closedType = openType.MakeGenericType(type);

Finally, use reflection to create an instance of that type.

object instance = Activator.CreateInstance(closedType);

As noted by xanatos in the comments, however, you should be aware that this results in a member of type object. To be able to manipulate the object without reflection, you have two choices.

  1. You can create a parent class, GenericClass, from which GenericClass<T> derives, and include methods on it that are common to all. (i.e. GenericClass contains members that don't need to use T.
  2. As Ingenu had mentioned in the comments on the question, you can create an interface IInterface, and then add a restriction on T, where T : IInterface. Then, you can cast instance to GenericClass<IInterface> and manipulate it that way. Obviously, type must implement IInterface in this case.

You can of course also just keep the object reference and manipulate it using reflection only, or use dynamic to late-bind any method calls -- this uses reflection under the hood, however.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文