为什么C#允许接口中的属性?


47

在C#中,以下代码有效

interface I{
    int property{get;set;}
}

这对我来说毫无意义。这似乎打破了接口最重要的原则之一:缺少状态(换句话说,没有字段)。该属性是否不会创建隐式私有字段?这对接口真的不好吗?


12
缺乏状态是接口实现的原理之一吗?对我而言,接口是定义合同的一种方式,即,如果一个类实现了这样的接口,则它具有合同中定义的所有方法和属性。
Florian Margaine 2014年

4
属性只是get方法和set方法。因为接口只是您必须实现的方法的列表,所以接口可以自然地拥有它们。
Doval

1
@FlorianMargaine当然,合同的概念是最重要的接口原理,但是缺少状态也很重要。这有助于将其与抽象类分开。Java 8中的IE最终是接口和抽象类之间的唯一主要区别。
恢复莫妮卡2014年

2
因为它不是一个领域。请参见为什么C#接口不能包含字段?

2
@Doval:很自然的,一个接口声明了这样的方法,但是并没有实现它们。
Giorgio

Answers:


65

我认为令人困惑的部分是,如果您int Property { get; set; }在类中编写代码,那么这是具有隐式支持字段的自动属性。

但是,如果您在接口中编写完全相同的内容,则它不是自动属性,它只是声明该属性是接口的一部分,并且实现该接口的任何类型都必须包含该属性(是否为自动属性) ),但不会创建后备字段。

观察差异的一种方法是编写int Property { get; }:这在接口中有效,并声明一个仅具有getter但没有setter的属性。但是它不会在类中编译(除非您使用的是C#6.0),因为自动属性必须有一个setter。


18

定义属性与定义方法int GetProperty()和相同void SetProperty(int i)。在C#中,属性是功能强大的简称。

属性不会在C#中隐式创建私有字段。也就是说的默认实现auto-property,例如public string MyString { get; set;}-然而,它定义在定制逻辑的属性get方法不产生隐式私有字段。

最后,由于接口与公共 API 有关,如果接口属性的实现依赖于私有字段(隐式或其他),那将有什么关系?无论如何,这对接口的使用者都是隐藏的。


啊...我没有意识到这仅适用于自动属性,并且由于您必须覆盖它,因此很有意义。但是,如果接口要创建内部私有变量,则实现者将无法访问它-一个明显的问题。
恢复莫妮卡2014年

9
如果在C#接口中定义属性,则该属性的实现将留给实现类-他们可以将其设置为自动属性,也可以根据需要定义自定义逻辑。没有字段添加到接口
NWard 2014年

10

属性就是方法!一个支持字段将添加到实现该接口的类中(手动或通过自动属性)。


有时将没有后备领域。尽管很少定义get和set并且没有后备字段。
斯蒂芬

+1 属性是方法! 是!我喜欢编写Propertymethod,但是代码审阅的同事却不这么认为,我们确实错过了在程序中添加一些漂亮的表达性封装的机会。
Radarbob 2014年

那些“属性方法”应该很快,就像没有数据库查找或其他任何东西一样。有一个隐含的约定,即属性访问速度很快,Get *方法可能很慢。
Trey Mack
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.