例如,假设我想要一个ICar接口,并且所有实现都将包含字段Year。这是否意味着每个实现都必须单独声明Year?在接口中简单地定义它不是更好吗?
当前回答
已经说了很多,但为了简单起见,这里是我的看法。 接口的目的是拥有由使用者或类实现的方法契约,而不是使用字段来存储值。
你可能会问为什么允许有财产?因此,简单的答案是—属性在内部只定义为方法。
其他回答
其他人已经给出了“为什么”,所以我只是补充说,你的界面可以定义一个控件;如果你把它包装在属性中:
public interface IView {
Control Year { get; }
}
public Form : IView {
public Control Year { get { return uxYear; } } //numeric text box or whatever
}
为什么不使用Year属性呢?
接口不包含字段,因为字段表示数据表示的特定实现,暴露它们会破坏封装。因此,拥有一个带有字段的接口将有效地编码到一个实现,而不是一个接口,这是一个奇怪的接口!
例如,部分Year规范可能要求ICar实现者允许赋值给比当前年份+ 1晚或1900年之前的年份是无效的。如果您已经公开Year字段,就无法这样说——在这里使用属性来完成工作要好得多。
从c# 8.0开始,接口可以为成员定义默认实现,包括属性。很少在接口中为属性定义默认实现,因为接口可能不定义实例数据字段。
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/interface-properties
interface IEmployee
{
string Name
{
get;
set;
}
int Counter
{
get;
}
}
public class Employee : IEmployee
{
public static int numberOfEmployees;
private string _name;
public string Name // read-write instance property
{
get => _name;
set => _name = value;
}
private int _counter;
public int Counter // read-only instance property
{
get => _counter;
}
// constructor
public Employee() => _counter = ++numberOfEmployees;
}
已经说了很多,但为了简单起见,这里是我的看法。 接口的目的是拥有由使用者或类实现的方法契约,而不是使用字段来存储值。
你可能会问为什么允许有财产?因此,简单的答案是—属性在内部只定义为方法。
尽管许多其他答案在语义层面上是正确的,但我发现从实现细节层面处理这类问题也很有趣。
接口可以看作是插槽的集合,插槽包含方法。当一个类实现一个接口时,该类需要告诉运行时如何填充所有必需的插槽。当你说
interface IFoo { void M(); }
class Foo : IFoo { public void M() { ... } }
这个类说:“当你创建一个我的实例时,填充一个对Foo的引用。M在IFoo.M的槽里。
然后当你打电话的时候:
IFoo ifoo = new Foo();
ifoo.M();
编译器会生成这样的代码:“询问对象IFoo的槽中有哪个方法。M,然后调用这个方法。
如果接口是包含方法的槽的集合,那么其中一些槽还可以包含属性的get和set方法、索引器的get和set方法以及事件的添加和删除方法。但是字段不是方法。没有与字段相关联的“槽”,然后您可以用字段位置的引用“填充”该字段。因此,接口可以定义方法、属性、索引器和事件,但不能定义字段。
推荐文章
- Selenium c# WebDriver:等待元素出现
- 我如何添加双引号的字符串,是在一个变量?
- 检查字符串是否包含字符串列表中的元素
- 最好的方法在asp.net强制https为整个网站?
- 将字符串转换为System.IO.Stream
- 如何从枚举中选择一个随机值?
- 驻留在App_Code中的类不可访问
- 在链式LINQ扩展方法调用中等价于'let'关键字的代码
- dynamic (c# 4)和var之间的区别是什么?
- Visual Studio: ContextSwitchDeadlock
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头
- 如果我使用OWIN Startup.cs类并将所有配置移动到那里,我是否需要一个Global.asax.cs文件?
- VS2013外部构建错误"error MSB4019: The imported project <path> was not found"
- 从另一个列表id中排序一个列表