实现缺少新约束的通用接口

时间:2017-02-15 10:52:12

标签: c# generics interface

考虑以下界面:

public interface IFoo
{
    M Bar<M>();
}

尝试用

实现它
class Foo : IFoo
{
    public M Bar<M>()
    {
        return new M();
    }
}

不起作用,编译器抱怨M缺少new()约束。

当我在

中添加约束时
class Foo : IFoo
{
    public M Bar<M>() where M : new()
    {
        return new M();
    }
}

这仍然无法解决问题,因为Foo.Bar的约束现在与接口方法的约束不匹配(而且我无法改变它)。

documentation for the compiler error CS0425

  

要避免此错误,请确保where子句在两者中都相同   声明,或明确实现接口。

如果&#34;明确实施界面&#34;是解决方案:我该怎么做?

3 个答案:

答案 0 :(得分:6)

如果您无法更改界面定义,则必须避免使用new M(); - 请改为使用Activator.CreateInstance

class Foo : IFoo
{
    public M Bar<M>()
    {
        return Activator.CreateInstance<M>();
    }
}

当然,如果M没有无参数构造函数,您现在可能会遇到运行时错误,但这是不可避免的(同样,因为我们无法更改通用约束)。

回复:文档:

  

明确实现接口。

认为他们试图在这里得到的是“如果你有一个具有一组通用约束的基类方法,并且你想要实现一个具有对于具有相同名称的方法的不同约束集,显式实现是该绑定的一种方法“。

答案 1 :(得分:5)

显式实现接口解决方案。编译器只是告诉你如果你需要一个带有该约束的泛型方法Bar,那么明确地实现接口,这样 Bar的两个版本可以共存,但是,显然,不是你所期待的解决方案。

唯一的解决方案是:

  1. 在界面中实现泛型类型约束。
  2. 通过反射M实例化新的Activator.CreateInstance,并在编译时支付丢失类型安全的代价;没有强制M拥有无参数构造函数。

答案 2 :(得分:0)

您可以通过右键单击类中的接口来生成显式接口实现,该接口应实现它并选择“明确实现”。方法名称应该用接口名称来表示。