【问题标题】:Is it possible to constrain the constructors of classes implementing an interface?是否可以约束实现接口的类的构造函数?
【发布时间】:2012-03-07 17:15:27
【问题描述】:

是否可以设置所有实现接口的类都必须具有的约束,例如,一个空的构造函数?就像泛型中的 where T : new() 约束一样?

【问题讨论】:

  • 不,不可能用接口约束构造函数。

标签: c# oop interface constructor


【解决方案1】:

我能想到的只有四种方法可以在运行时为您提供一个在编译时不知道的类。您可能会得到一个实现接口的对象的实例,并希望生成另一个类似的对象。这种情况最好通过让接口包含NewSimilarInstance() 方法来处理。您可能在某个类中有一个方法,该方法传递了一个泛型类型参数,该类型参数受限于您的接口。在这种情况下,接受泛型参数的例程可能具有new() 约束。否则,您可能会得到一个 .net System.Type 对象或该类型的其他一些表示形式(例如字符串)。在后两种情况下,没有编译时验证是有意义的;对这些类型进行任何操作都需要反射,因此您不妨使用反射来查看它们是否允许创建新实例。

【讨论】:

  • 这是前两种情况的混合体。我认为您对NewSimilarInstance() 的建议在我的情况下是一个很好的建议。谢谢!
【解决方案2】:

将工厂注入到可以实例化接口的泛型类中,并删除 new() 约束。

类似:

public interface IFactory<out T>
{
    T CreateInstance();
}

public class GenericClass<T>
{
     private readonly IFactory<T> _factory;

     public GenericClass(IFactory<T> factory)
     {
          _factory = factory;
     }

     public DoSomething()
     {
          //...
          T foo = _factory.CreateInstance();
          //...
     }
}

【讨论】:

    【解决方案3】:

    否 - 不可能对给定接口的派生类或实现者施加任何此类约束。

    这样的约束通常不会是一个特别好的主意/无论如何都不会有用,因为通常在使用接口时,您通常使用实现该接口的对象实例,在这种情况下,对象自然已经被创建并且这样的约束是多余的。 (当然泛型除外,在这种情况下您可以使用new() 约束)。

    我的猜测是您正在尝试创建某种插件系统并希望约束您的插件接口的实现以具有一些可用于实例化的默认构造函数......如果是这种情况,那么通常会有更好的您可以使用的替代方案,例如 MEF

    您能否详细说明您究竟为什么需要这个?

    【讨论】:

    • 我想使用带有接口类型参数的泛型类型(比如 IFoo),不幸的是我发现我们需要在一个非常特殊的条件下构造一个 IFoo 对象。 (我知道,这不好)。我可以在泛型类型上设置一个 new() 约束,但它不起作用,因为 IFoo 没有 new()
    【解决方案4】:

    正如贾斯汀所说,您不仅不能使用接口来约束构造函数签名,而且也不可能使用抽象类。 也许如果你能解释为什么你需要放置这样的约束,我们可以为你的问题找到一些其他的解决方案

    【讨论】:

      【解决方案5】:

      我认为您需要为此使用虚拟类。

      【讨论】:

      • 你的意思是抽象类吗?
      • 是的,我的错。我最近一直在做很多 vb,这让我很困惑。
      【解决方案6】:

      不,没有那样的东西。这会有点奇怪,因为接口的正常使用是使用接口的代码不需要关心它是如何实例化的——他们不应该关心实现类是什么,只关心它实现了接口.

      如果您对此有特殊用途,我建议您只为它编写单元测试 - 如果所有实现都在同一个程序集中,那么这样做应该非常简单,并且会在 几乎与编译时间...

      【讨论】:

        猜你喜欢
        • 2012-09-28
        • 1970-01-01
        • 2020-02-26
        • 2011-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多