C#readonly vs Get

readonly修饰符和get-only属性之间是否有任何区别?

例:

public class GetOnly { public string MyProp { get; } } public class ReadOnly { public readonly string MyProp; } 

额外奖励:有没有办法让界面与两者兼容? (与generics一起使用)

 public interface ISomething { public string MyProp { get; } } public class GetOnly : ISomething { public string MyProp { get; } } public class ReadOnly : ISomething // Cannot implement { public readonly string MyProp; } 

提前谢谢了!

乍一看,属性和字段在function上是等价的,对于正常使用情况,存储数据并将其传递到那里使用它们没有太大区别。

但您似乎已经发现了一个重要问题:只有属性才能成为界面的一部分。

有没有办法使界面适用于两者?

没有。

此外,许多依赖于reflection(EF,序列化)的API专门寻找属性。

你从根本上误解了这两个定义的含义。 只暴露getter才会说明值是否为只读。

虽然在这个简单的例子中:

 public class GetOnly { public string MyProp { get; } } 

我们可以说MyProp 永远不会改变它的价值,我们不能总是说只有getter的属性不会改变它的值。 这种情况的一个例子是我们无法看到GetOnly的实现,只知道公共定义 – 例如,如果您正在使用闭源第三方库。

一个更清楚的例子是这样的:

 public interface ISomething { string MyProp { get; } } 

此接口并未说MyProp是只读的。 它说不能改变财产。 它没有说明财产的行为。 更糟糕的是,它只表示在显式转换为ISomething时无法更改属性。

完全可以像这样实现接口(即使接口只暴露了getter):

 public class GetOnly : ISomething { public string MyProp { get; set; } } 

readonly是一个修饰符,它明确强制该值不会发生变化的事实,除了声明或构造函数 (禁止像reflection这样的变通方法)。

但是, readonly无法处理属性,因为属性只是get / set 方法的语法糖。 此外,接口只定义方法,因此您无法定义字段(以及扩展名,只读字段)。

所以回答你的答案:是的,它们是世界分开的,只是表面上相似。

一个是一个领域( readonly ); 另一个是财产。 接口不能定义字段,只能定义属性,方法,索引器和事件。

两者都只能通过构造函数或字段初始化分配,并且此后不能更改。

在以下部分中:

 public class GetOnly { public string MyProp {get; } } 

MyProp是一个属性 。 但是,在这部分:

 public class ReadOnly { public readonly string MyProp; } 

MyProp是一个领域 。 这是两件不同的事情。

有没有办法使界面适用于两者?

不可以。只有属性可以放入接口。 字段不能。