【问题标题】:using the original type or a Type object in generics在泛型中使用原始类型或 Type 对象
【发布时间】:2012-09-27 05:52:02
【问题描述】:

如果您给定一个类型对象,例如

var myType = typeof(SomeClass)

是否可以获得原始类型,作为接口或类并在泛型中使用它。

例如

var myObject = container.Resolve<myType>()

所以这会在这种情况下创建一个 SomeClass 类型的对象。

为了澄清我正在尝试围绕 Ioc 容器创建一个包装器,以便 Ioc 框架可以在不影响任何其他代码的情况下进行更改。

【问题讨论】:

  • 是的,使用反射。如果您无法使其工作,请尝试发布您编写的代码。
  • 你需要从IoC容器中获取吗?
  • 对于这种特殊的问题,它是一个围绕 IoC 容器的包装类

标签: c# .net generics


【解决方案1】:

如果container.Resolve 表示UnityContainer.Resolve 家族之一,那么overload 接受Type 实例:

var obj = container.Resolve(typeObj);

对于 DI 或 IoC 容器,具有耦合解析重载、通用用例和非通用用例是一个常见特性。

【讨论】:

  • 有点意思,我正在尝试为 ioc 容器创建一个包装类,以便 ioc 实现可以更改而不会影响任何其他代码。作为一种解决方法,我已经这样做了,但目前的国际奥委会是城堡,但他们也支持这一点。
  • @RyanBurnham:如果你想写一个包装器,那么你应该决定你将支持什么分辨率方案。对于泛型,你必须有类似'T MyIoCWrapper.Resolve'的东西,它将调用重定向到适当的底层容器的Resolve&lt;T&gt;重载(也是泛型的!)。对于非泛型,会有object MyIoCWrapper.Resolve(Type),它将调用容器的Resolve(Type)。我认为这里不需要反射或表达式使用。
  • 我面临的问题是当前 IoC 容器有一些紧密耦合的代码,其中它采用接口类型并查询容器以获取为该类型注册的任何对象。最好只使用 Resolve(Type) 方法。
  • @RyanBurnham:接口类型在编译时是否已知?
  • @RyanBurnham:嗯,object Resolve(Type) 是你能做的最好的。
【解决方案2】:

完全不清楚“获取原始类型”是什么意思 - 但如果您想在泛型中使用该类型,您通常需要使用反射。例如:

var methodDefinition = container.GetType().GetMethod("Resolve");
var constructedMethod = methodDefinition.MakeGenericMethod(method);
object myObject = constructedMethod.Invoke(container, null);

myObject 变量的类型只能是 object - 变量的类型必须在编译时知道(尽管它可以是通用的)。如果您使用 C# 4 和 .NET 4+,您可能会使用 dynamic 作为替代方案 - 这取决于您之后尝试使用它做什么。

如果您发现自己必须使用相同的类型参数进行多次反射调用,请考虑将逻辑提取到一个新的泛型方法中 - 然后您可以使用反射一次来调用该方法,然后只需在方法中使用普通泛型。

【讨论】:

    【解决方案3】:

    我猜,你需要这样的东西:

    T Resolve<T>()
    {
        var myType = typeof(T);
        return (T)myType.GetConstructor(new Type[] { }).Invoke(new object[] { });
    }
    

    你使用它:

    YourClass l = Resolve<YourClass>();
    

    这是一个非常简单的构造函数示例,没有类似的参数

    public YourClass(){...}
    

    你可以从herehere开始阅读

    无论是否需要反思,您都应该始终仔细考虑(考虑 J.Skeet 给出的答案)。

    【讨论】:

    • 嗯,不会太复杂吧? T Resolve&lt;T&gt;() where T : new() {return new T();} 。这不是那么有趣,但也一样......
    • @RaphaëlAlthaus 我说这只是一个例子......他可能需要使用带参数的构造函数
    猜你喜欢
    • 2013-10-04
    • 2020-12-03
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多