C#readonly vs Get

时间:2016-05-28 08:09:21

标签: c# properties

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

示例:

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

public class ReadOnly
{
    public readonly string MyProp;
}

Bonus:有没有办法让界面兼顾两者? (与泛型一起使用)

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;
}

非常感谢提前!

4 个答案:

答案 0 :(得分:19)

您从根本上误解了这两种定义的含义。只暴露getter说 nothing 是否值是只读的。

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

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 方法的语法糖。此外,接口只定义方法,因此您无法定义字段(以及扩展名,只读字段)。

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

答案 1 :(得分:14)

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

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

  

有没有办法让界面与两者兼容?

没有

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

答案 2 :(得分:2)

在以下部分中:

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

MyPropproperty。但是,在这一部分:

public class ReadOnly
{
    public readonly string MyProp;
}

MyPropfield。这是两件不同的事情。

  

有没有办法让界面与两者兼容?

没有。只能将属性放入接口。字段不能。

答案 3 :(得分:2)

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

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