例如,假设我想要一个ICar接口,并且所有实现都将包含字段Year。这是否意味着每个实现都必须单独声明Year?在接口中简单地定义它不是更好吗?


当前回答

Eric Lippert说的很好,我会用另一种方式来表达他说的话。接口的所有成员都是虚的,它们都需要被继承该接口的类重写。你不需要在接口声明中显式地编写virtual关键字,也不需要在类中使用override关键字,它们是隐含的。

在. net中,virtual关键字是通过方法和所谓的v-table(方法指针数组)实现的。override关键字用不同的方法指针填充v-table槽,覆盖基类生成的方法指针。属性、事件和索引器是作为方法实现的。但是田野不是。因此,接口可以不包含字段。

其他回答

简短的回答是肯定的,每个实现类型都必须创建自己的支持变量。这是因为接口类似于契约。它所能做的就是指定实现类型必须提供的特定的公开可访问的代码段;它本身不能包含任何代码。

用你的建议来考虑这个场景:

public interface InterfaceOne
{
    int myBackingVariable;

    int MyProperty { get { return myBackingVariable; } }
}

public interface InterfaceTwo
{
    int myBackingVariable;

    int MyProperty { get { return myBackingVariable; } }
}

public class MyClass : InterfaceOne, InterfaceTwo { }

这里有几个问题:

因为接口的所有成员(根据定义)都是公共的,所以我们的备份变量现在暴露给使用该接口的任何人 MyClass将使用哪个myBackingVariable ?

最常用的方法是声明接口和实现它的基本抽象类。这使得您可以灵活地从抽象类继承并免费获得实现,或者显式地实现接口并允许从另一个类继承。它是这样工作的:

public interface IMyInterface
{
    int MyProperty { get; set; }
}

public abstract class MyInterfaceBase : IMyInterface
{
    int myProperty;

    public int MyProperty
    {
        get { return myProperty; }
        set { myProperty = value; }
    }
}

c#中的接口旨在定义类将遵循的契约——而不是特定的实现。

基于这种精神,c#接口确实允许定义属性——调用者必须为其提供一个实现:

interface ICar
{
    int Year { get; set; }
}

实现类可以使用auto-properties来简化实现,如果没有与属性相关的特殊逻辑的话:

class Automobile : ICar
{
    public int Year { get; set; } // automatically implemented
}

接口不包含任何实现。

定义带有属性的接口。 此外,您可以在任何类中实现该接口,并继续使用该类。 如果需要,可以在类中将此属性定义为virtual,以便修改其行为。

其他人已经给出了“为什么”,所以我只是补充说,你的界面可以定义一个控件;如果你把它包装在属性中:

public interface IView {
    Control Year { get; }
}


public Form : IView {
    public Control Year { get { return uxYear; } } //numeric text box or whatever
}

已经说了很多,但为了简单起见,这里是我的看法。 接口的目的是拥有由使用者或类实现的方法契约,而不是使用字段来存储值。

你可能会问为什么允许有财产?因此,简单的答案是—属性在内部只定义为方法。