繁体   English   中英

抽象类型和交互作用的问题作为泛型类型params与new()约束

[英]Problems with abstract types and interafaces as generic type params with the new() constraint

我需要将泛型类型参数作为接口,但是我想在泛型类(SomeGenericType)中实例化类型,如下所示:

class Program
{
    static void Main(string[] args)
    {
        var val = new SomeGenericType<ISomeInterface>();

        Console.ReadKey();
    }
}

internal class SomeGenericType<T> where T : new()
{
    public SomeGenericType()
    {
        var test = new T();  
    }
}

public class SomeClass : ISomeInterface
{
    public string TestVal { get; set; }
}

public interface ISomeInterface
{
    string TestVal { get; set; }
}

这会抛出以下编译时错误:

“ISomeInterface必须是具有公共无参数构造函数的非抽象类型,以便在泛型类型或方法SomeGenericType中将其用作参数'T'”

我理解为什么会这样,但是我想知道这个问题是否有任何解决办法?

谢谢。

不, new()约束要求可以使用语法创建该类型的实例

new T()

这显然不适用于抽象类或接口,只是具有公共无参数构造函数的具体类。

您可以通过删除约束将问题推迟到运行时,并使用:

Activator.CreateInstance<T>()

而是创建对象。 然后,只要运行时使用的实际类型满足这些约束,您的代码就会按照您的意愿运行。 但是,如果您尝试使用接口或抽象类,则会遇到运行时错误。

在您的特定情况下,此行将引发异常

var val = Activator.CreateInstance<SomeGenericType<ISomeInterface>>();

您已经过了编译时错误,但没有效果。

一个替代的想法,可能是无关紧要的,但看起来你正在寻找一种方法来要求一个ISomeInterface ,并有一个其默认的实现SomeClass提供的实例。 这是控制反转(IOC)容器可以为您处理的事情。 如果您想进一步调查,可以查看Spring.NET,Microsoft Unity,AutoFac,LinFu或许多其他框架之一。

这里的问题是new约束与具体类型实现有关。 这不能用于简单的接口或抽象类,因为它们不能直接实例化。 你必须在这里提供一个具体的课程

var val = new SomeGenericType<SomeClass>()

问题是,编译器无法知道为给定接口实例化哪个类。 正如大卫M指出:

这是控制反转(IOC)容器可以为您处理的事情

我认为使用框架可能会因为这个简单的要求而过度杀戮。 你可以做的就是像这样创建一个自己的Factory类:

public class Factory
{
  Dictionary<Type, Type> typeMapping = new Dictionary<Type, Type>();

  public void Register<IType, CType>()
  {
    typeMapping.Add(typeof(IType),typeof(CType));
  }

  public IType Create<IType>()
  {
    Activator.CreateInstance(typeMapping[typeof(IType)]);
  }
}

投入一些健全性检查,这个课程应该可以使用了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM