Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么不允许在接口中指定构造函数?_C#_.net_Vb.net_Oop - Fatal编程技术网

C# 为什么不允许在接口中指定构造函数?

C# 为什么不允许在接口中指定构造函数?,c#,.net,vb.net,oop,C#,.net,Vb.net,Oop,可能重复: 我知道你不能在.Net的接口中指定构造函数,但为什么我们不能呢 对于我当前的项目来说,能够指定“引擎”必须与构造函数一起传递是非常有用的,但是我不能,我必须在类上添加XML注释。因为你不能实例化接口,所以构造函数没有意义 如何调用构造函数?使用接口时,通常会传递接口的实例(或者更确切地说,传递引用)。还要记住,如果一个类实现了一个接口,则派生类继承该接口,但可能没有相同的构造函数集 现在,我可以看到我所称的静态接口用于指定构造函数和其他基本上是静态的成员,以便在泛型方法中使用。有关

可能重复:

我知道你不能在.Net的接口中指定构造函数,但为什么我们不能呢


对于我当前的项目来说,能够指定“引擎”必须与构造函数一起传递是非常有用的,但是我不能,我必须在类上添加XML注释。

因为你不能实例化接口,所以构造函数没有意义

如何调用构造函数?使用接口时,通常会传递接口的实例(或者更确切地说,传递引用)。还要记住,如果一个类实现了一个接口,则派生类继承该接口,但可能没有相同的构造函数集


现在,我可以看到我所称的静态接口用于指定构造函数和其他基本上是静态的成员,以便在泛型方法中使用。有关更多信息,请参阅。

,因为接口描述行为。构造函数不是行为。如何构建对象是一个实现细节。

不,由于已发布的原因,您不能在接口上使用构造函数。但是,您可以在抽象类上使用。例如,假设您有这个基类

public abstract class ClassOne
{
    protected int _x;
    protected string _s;

    public ClassOne(int x, string s)
    {
        _x = x;
        _s = s;
    }        
}
请注意,没有不带参数的构造函数(默认构造函数),这意味着从ClassOne继承的任何类都必须调用具有2个参数的构造函数

所以这是无效的,不会编译

public class ClassTwo : ClassOne
{
    public ClassTwo() 
    { }
}
但是,这是有效的,并将编译

public class ClassTwo : ClassOne
{
    public ClassTwo(int x, string s) : base(x, s)
    {  }
}
我想在此指出,在C#中,只能从一个基类继承。这意味着,对于特定情况,这可能不是正确的解决方案,但需要考虑


Tony。

在已经发布的所有其他原因中,还要记住a类可以轻松实现多个接口;那么应该使用哪个构造函数?

其他答案已经指出了为什么在接口上声明构造函数没有意义。但从你的问题来看,我猜你可能是在寻找答案

根据您的问题给出一个示例:您说您想以某种方式声明必须将“引擎”传递给构造函数。可以通过如下方式为构造服务声明单独的接口来实现:

public interface IGadgetFactory
{
   IGadget CreateGadget(Engine engine);
}

任何必须创建
IGadget
实例的代码都可以使用
IGadgetFactory
实例,而不是直接调用任何构造函数。

除了这里给出的其他解释之外,您还必须发明一种新的语法来调用它们,因为如果在同一行的作用域中有两个或多个实现:

Dim x as new IDoStuff()

调用哪种实现?

有一种非常好的语法,用于实现具有相同签名的接口方法,该签名可用于构造函数。我不确定我是否理解你的观点(可能我没有):我的意思是,类a可以使用无参数的构造函数实现接口IAlpha,IBeta有一个带一个参数的构造函数,IGamma有一个带两个参数的构造函数:哪个构造函数应该为a类实现?啊,这是唯一对我有意义的答案。所有不能实例化接口的参数都会让我问“那又怎样?”接口的要点是声明必须在假定实现接口的任何类中实现这样或那样的函数集。说这样一个类还必须实现一个使用这组特定参数的构造函数,这听起来很合理。但是冲突的构造器论点,现在提出了一个问题。完全同意Jay的观点。虽然我相信通过接口强制构造函数签名不是一个荒谬的想法,但还需要更多的思考。对于.net来说,简单地禁止使用相同的方法签名实现接口并不难。事实上,它不是这样做的吗?如果不是的话,我认为应该忽略构造函数的问题。我认为这给实现细节赋予了太多的意义:在.NET中,构造函数实际上只是一个在对象创建(分配到内存中)后立即被调用的方法。没有理由不能将其定义为行为。当然,实现也可以自由声明其他构造函数,就像它们可以重载实现接口的方法一样。接口中的构造函数将是一个很少使用的特性,但不是一个无用的特性。我认为问题的关键是:既然它是以这种方式构建的,那么最佳实践是什么?所以我想答案是:通过使用抽象类,正如这个答案所说:公共构造函数显然是API的一部分。如果不是行为,那还能是什么?+1我认为这将是对.NET的一个很好的补充,并且我已经对相关的连接反馈项进行了升级:我可以想到接口的三个类功能:(1)方法或属性的默认实现(请注意,继承的接口将无法覆盖基接口的默认实现);(2) 允许同一标识符有效地兼作接口和静态类;(3) 定义在接口上调用“new”时要使用的静态方法。注意#2和#3是语法上的糖,但我认为它们会使一些东西更干净。如果.net支持#1,接口可以添加新的方法或属性,而不会破坏现有的实现。@supercat:是的,我也考虑过1一段时间了——我相信MS也是如此。万斯·莫里森在接受采访时谈到了这一点。我很好奇地想知道他在做什么;我还想知道,当构造函数抛出异常时,微软是否添加了清理IDisPobles的好方法,或者(对于vb)是否有一种方法可以自动终止所有WithEvents订阅。我看到了一些关于新特性的老讨论的链接;你有什么最新的吗?@supercat:恐怕不知道。我没有