C# 如何强制类实现构造函数?

C# 如何强制类实现构造函数?,c#,interface,class-design,abstract-class,C#,Interface,Class Design,Abstract Class,我有一个接口IPopUp: public interface IPopUp { bool IsCancelable {get;} void Show(); void Close(); Action MainAction{ get; } Action CancelAction{ get; } } 我有几个实现:IfoPopUp,ErrorPopUp,和LoadingPopUp 我正在使用PopUpManager实例创建popup的实例 public

我有一个接口
IPopUp

public interface IPopUp 
{
    bool IsCancelable {get;}
    void Show();
    void Close();
    Action MainAction{ get; }
    Action CancelAction{ get; }
}
我有几个实现:
IfoPopUp
ErrorPopUp
,和
LoadingPopUp

我正在使用
PopUpManager
实例创建
popup
的实例

   public class PopUpManager
   {
      public void ShowPopUp<T>(string texto) where T:IPopUp 
      {
        ShowPopup (()=>(IPopUp)Activator.CreateInstance (typeof(T)));
      }

      public void ShowPopUp<T>(string texto,Action mainAction)where T:IPopUp 
      {
        ShowPopup (()=>(IPopUp)Activator.CreateInstance (typeof(T), mainAction));
      }

      public void ShowPopUp<T>(string texto,Action mainAction,Action cancelAction)where T:IPopUp 
     {
        ShowPopup (()=>(IPopUp)Activator.CreateInstance (typeof(T), mainAction, cancelAction));
     }

     private void ShowPopup(Func<IPopUp> factoryFunc)
     {
        if (PopUpShowed != null) {
            PopUpShowed.Close ();
        }
        IPopUp popUp = factoryFunc ();
        popUp.Show ();
     } 
}
公共类PopUpManager
{
公共void ShowPopUp(字符串texto),其中T:IPopUp
{
ShowPopup(()=>(IPopUp)Activator.CreateInstance(typeof(T));
}
public void ShowPopUp(字符串texto,Action mainAction),其中T:IPopUp
{
ShowPopup(()=>(IPopUp)Activator.CreateInstance(typeof(T),mainAction));
}
public void ShowPopUp(字符串texto,Action main Action,Action cancelAction),其中T:IPopUp
{
ShowPopup(()=>(IPopUp)Activator.CreateInstance(typeof(T)、mainAction、cancelAction));
}
私有无效显示弹出窗口(Func factoryFunc)
{
如果(弹出显示!=null){
关闭();
}
IPopUp popUp=factoryFunc();
Show();
} 
}
我不知道如何强制
IPopUp
实现实现我在
PopUpManager
中使用的3种构造函数。 抽象类无法工作,因为它可以强制构造函数。。。
有什么想法吗?

我最终重构了类
PopUpManager
,因此它需要一个工厂委托来生成
弹出窗口。
是非常清楚的,实例化弹出窗口的责任来自于有很多意义的调用方

public void ShowPopUp(Func<IPopUp> factoryFuncPopUp)
{
    if (PopUpShowed != null) {
        PopUpShowed.Close ();
    }
    IPopUp popUp = factoryFuncPopUp();
    popUp.Show ();
}
public void ShowPopUp(Func factoryFuncPopUp)
{
如果(弹出显示!=null){
关闭();
}
IPopUp popUp=factoryFuncPopUp();
Show();
}

无论如何,我想知道哪种方法最适合强制类实现某种构造函数。

您已经找到了一个很好的解决方案。这里有一些关于强制类实现某些构造函数的额外见解

可以用接口来完成吗? 第13章定义了什么是接口:

接口定义了一个契约。实现 接口必须遵守其合同。接口可以继承自 多个基本接口,一个类或结构可以实现多个 接口
接口可以包含方法、属性、事件和 索引器。接口本身不提供 它定义的成员。接口仅指定 必须由实现 接口

实例构造函数不是方法,不能是接口的一部分。13.2中明确提醒了这一点:

接口不能包含常量、字段、运算符和实例 构造函数、析构函数或类型,接口也不能包含 任何类型的静态成员

有很多理由可以证明这种语言设计的选择是正确的,你可以找到一些其他的解释。还要注意,其他语言也有类似的约束。例如,Java声明“接口不能直接实例化”

可以用抽象类来完成吗? C语言规范在第10.1.1.1节中说明。即:

抽象修饰符用于指示类不完整 而且它只打算用作基类。(…)抽象类不能直接实例化,在抽象类上使用新运算符是编译时错误

长话短说,如果要在一个抽象类中定义三个不同的构造函数,则派生类必须调用其中一个构造函数,但不对它们自己的构造函数进行任何约束。请注意,这个逻辑也适用于C++或java。 抽象类与其派生类之间的链接类似于
形状
与实现
形状
正方形
矩形
圆形
之间的链接:矩形的构造参数可能与圆形的构造参数非常不同,因此,
形状
不能对其子级的构造函数施加约束

可以用一个组合吗? 您希望
PopupManager
实例化具有特定属性的
IPopUp
。不幸的是,您不能以安全的方式直接实例化
IPopUp
(可能会触发异常)

为了安全起见,您可以强制
IPopUp
MainAction
CancelAction
要求一个setter,并添加一个构造函数约束(例如
where T:IPopUp,new()
),以确保可以毫无意外地创建一个实例,并根据需要修改对象


但在某些情况下,需要在施工时提供参数。在这种情况下,您可以考虑使用您选择的或工厂方法。请注意,在允许使用静态成员的接口的语言中,甚至可以在
IPopUp
接口中强制使用三种静态工厂方法。

我也遇到了类似的问题。在我的例子中,具有特定属性
[SpecialAttribute]
的类需要具有无参数构造函数

我添加了一个测试,在每次构建之后在我们的CI服务器上运行,在那里搜索具有该属性的类,然后调用
Activator.CreateInstance
。如果由于
MissingMethodException
s而失败,该测试将“失败”,并显示缺少无参数构造函数的类


这并不完美,因为代码仍然可以编译。但是一个失败的自动测试和一条清晰的消息是向前迈出的重要一步。

为什么需要强制类具有构造函数?如果没有,会出现什么问题?不幸的是,最好的答案是不要使用接口。现在还不清楚为什么这里使用one而不是抽象基类