投射使用反射创建的泛型类型实例

编程入门 行业动态 更新时间:2024-10-26 14:36:54
本文介绍了投射使用反射创建的泛型类型实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用反射创建泛型类型的实例:

I'm creating instances of a generic type using reflection:

public interface IModelBuilder<TModel> { TModel BuildModel(); } public class MyModel { public string Name { get; set; } } public class MyModelBuilder : IModelBuilder<MyModel> { public MyModel BuildModel() { throw new NotImplementedException(); } }

在运行时,我们所知道的只是模型的类型,例如 MyModel .我可以找到相关模型构建器的实例,如下所示:

At runtime all we know is the Type of model e.g. MyModel. I can find instances of the relevant model builder like so:

var modelBuilders = from t in Assembly.GetExecutingAssembly().GetTypes() from i in t.GetInterfaces() where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IModelBuilder<>) && i.GetGenericArguments()[0] == modelType select t; var builder = Activator.CreateInstance(modelBuilders.First());

但是我不确定如何将实例转换为 IModelBuilder< TModel> ,以便我可以调用和使用 BuildModel()的结果./p>

But I'm not sure how I can then cast the instance as IModelBuilder<TModel> so I can call and work with the result of BuildModel().

推荐答案

由于 modelType 只是一个 Type 实例,由于存在没有可用的非通用API.各种选项:

Since modelType is just a Type instance, you can't do that automatically, since there is no non-generic API available. Various options:

1:例如,使用反射(未测试)

1: use reflection, for example (untested)

object builder = Activator.CreateInstance(...); var model=builder.GetType().GetMethod("BuildModel").Invoke(builder,null);

2:使用 dynamic 进行作弊:

dynamic builder = Activator.CreateInstance(...); var model = builder.BuildModel();

3:制作 IModelBuilder 的非通用版本,并使用该版本

3: make a non-generic version of IModelBuilder, and use that

请注意,1&2依赖于接口的公共实现,并且对于(完全合法的)显式接口实现将失败.对于"1",您可以通过以下方法解决此问题:

Note that 1 & 2 rely on a public implementation of the interface, and will fail for a (perfectly legal) explicit interface implementation. For "1", you can fix this via:

var model = typeof(IModelBuilder<>).MakeGenericType(modelType) .GetMethod("BuildModel").Invoke(builder);

最后一个偷偷摸摸的选择是将非泛型方法转换为泛型方法,因此在泛型方法内部,您可以直接使用所有成员.有一种偷懒的方法可以通过 dynamic :

A final sneaky option is to flip from a non-generic method into a generic method, so inside the generic method you can use all the members directly. There's a lazy way to do that via dynamic:

interface ISneaky<T> { T Foo { get; } } class Sneaky<T> : ISneaky<T> { T ISneaky<T>.Foo { get { return default(T); } } } class Program { static void Main() { Execute(typeof(int)); } static void Execute(Type t) { dynamic obj = Activator.CreateInstance( typeof(Sneaky<>).MakeGenericType(t)); // crafy hack to flip from non-generic code into generic code: Evil(obj); } static void Evil<T>(ISneaky<T> sneaky) { // in here, life is simple; no more reflection Console.WriteLine("{0}: {1}", typeof(T).Name, sneaky.Foo); } }

更多推荐

投射使用反射创建的泛型类型实例

本文发布于:2023-11-02 15:12:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1552730.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:反射   实例   类型

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!