将运行时生成的类型(通过 TypeBuilder)传递给 GenericClass

发布于 2024-10-28 12:35:09 字数 549 浏览 6 评论 0原文

我想将运行时生成的类型(通过 TypeBuilder)传递给泛型类中的泛型方法。我无法将其作为对象传递,因为反射用于查找各种属性。

据我了解,这是无法完成的,因为泛型是在编译时而不是运行时应用的。

我知道我可以将一个方法更改

public T Read()
{
     T data = new T()
     ...
     return data;
}

为类似

public object Read(Type newType)
{
     object data =  Activator.CreateInstance(newType);  
     ...
     return data;
}

的方法,但是当类型已知时,这显然会失去泛型的所有优点,所以我可能会以这两种方法结束,不幸的是,这意味着还要复制相当多的其他辅助函数。

有没有更好的方法来解决这个问题?

这个特定的项目需要在 3.5 框架下工作,但如果在 3.5 中不可能,但在 4.0 下,我不介意知道。

I would like to pass a type that is generated at runtime (via TypeBuilder) to a generic method in a generic class. I can't pass it as object as reflection is used to look up various properties.

As I understand, this can't be done as generics are applied at compile-time rather than run-time.

I know I can change an method like

public T Read()
{
     T data = new T()
     ...
     return data;
}

to be something like

public object Read(Type newType)
{
     object data =  Activator.CreateInstance(newType);  
     ...
     return data;
}

but this obviously loses all the advantages of generics when the type is known, so I will probably end with both methods, which unfortunately means also duplicating quite a few other other helper functions.

Is there any better way of resolving this issue?

This particular project needs to work under the 3.5 framework, but if it isn't possible in 3.5, but is under 4.0, I wouldn't mind knowing.

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

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

发布评论

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

评论(1

浅黛梨妆こ 2024-11-04 12:35:09

假设Read()类Reader的成员;其中 T : new(),您可以像这样调用通用版本(如果您有多个名为 Read< 的方法,则可能使用 GetMethod() 的另一种重载/code> 在该类型上):

Type readerType = typeof(Reader<>).MakeGenericType(generatedType);
object result = readerType
                  .GetMethod("Read")
                  .Invoke(Activator.CreateInstance(readerType), new object[0]);

这样,您就可以在 Read() 内部获得泛型的优势,而不是在外部。根据您想要做什么,也许使用接口而不是泛型会更好。可以通过为每个生成类型生成工厂类型来模拟 new() 约束,这些类型实现以下(非生成)接口:

interface IWhatever { … }

interface IWhateverFactory
{
    IWhatever Create();
}

Assuming Read() is a member of class Reader<T> where T : new(), you can call the generic version like this (possibly using another overload of GetMethod() if you have more than one method with the name Read on that type):

Type readerType = typeof(Reader<>).MakeGenericType(generatedType);
object result = readerType
                  .GetMethod("Read")
                  .Invoke(Activator.CreateInstance(readerType), new object[0]);

This way, you have the advantage of generics inside Read(), but not outside. Depending on what you want to do, maybe it would be better to use interfaces instead of generics. The new() constraint can be emulated by generating a factory type for every generated type, the types implementing the following (non-generated) interfaces:

interface IWhatever { … }

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