简体   繁体   English

C#readonly vs Get

[英]C# readonly vs Get

Are there any differences between the readonly modifier and get-only properties? readonly修饰符和get-only属性之间是否存在任何差异?

Example: 例:

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

public class ReadOnly
{
    public readonly string MyProp;
}

Bonus: is there a way to make an interface that works with both? 奖励:有没有办法使界面适用于两者? (to use with 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;
}

Many thanks in advance! 提前谢谢了!

You're fundamentally misunderstanding the meaning of both of those definitions. 你从根本上误解了这两个定义的含义。 Only exposing the getter says nothing about whether or not a value is read-only. 只露出吸气只字未提值是否为只读。

While in this trivial example: 虽然在这个简单的例子中:

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

We can say that MyProp will never change its value, we cannot always say that a getter-only property will not have its value changed. 我们可以说MyProp 永远不会改变它的价值,我们不能总是说只有getter的属性不会改变它的值。 An example of this is a situation where we cannot see the implementation of GetOnly , and only know about the public definition - For example, if you were working with a closed-source third party library. 这方面的一个例子是一种情况,我们无法看到的实施GetOnly ,只有了解公共定义-例如,如果你用一个封闭源代码的第三方库的工作。

A clearer example is this: 一个更清楚的例子是:

public interface ISomething
{
    string MyProp { get; }
}

This interface does not say that MyProp is read-only. 此接口并未说MyProp是只读的。 It says that you cannot change the property. 它说不能改变财产。 It says nothing about the behavior of the property. 它没有说明财产的行为。 Even worse, it only says you cannot change the property when explicitly casting as ISomething . 更糟糕的是,它只表示在显式转换为ISomething时无法更改属性。

It's entirely possible to implement the interface like so (even though the interface only exposes the getter): 完全可以像这样实现接口(即使接口只暴露了getter):

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

readonly is a modifier which explicitly enforces the fact that the value will not ever change, except in the declaration or constructor (barring workarounds like reflection ). readonly是一个修饰符,它明确强制该值不会发生变化的事实,除了在声明或构造函数中 (禁止像反射这样的变通方法)。

However, readonly cannot work on properties, as properties are simply syntactic sugar for get/set methods . 但是, readonly无法处理属性,因为属性只是get / set 方法的语法糖。 Further, interfaces only define methods, and as such you cannot define fields (and by extension, readonly fields). 此外,接口只定义方法,因此您无法定义字段(以及扩展名,只读字段)。

So to answer your question: Yes, they are worlds apart, and are only similar on the surface. 所以回答你的问题:是的,它们是世界分开的,只是表面上相似。

At first glance the property and the field are functionally equivalent and for the normal use cases of storing data and passing it around there is not much difference in using them. 乍一看,属性和字段在功能上是等价的,对于正常使用情况,存储数据并将其传递到那里使用它们没有太大区别。

But you already seem to have found an important issue: Only properties can be part of an interface. 但您似乎已经发现了一个重要问题:只有属性才能成为界面的一部分。

is there a way to make an interface that works with both? 有没有办法使界面适用于两者?

No. 没有。

In addition, many APIs that rely on reflection (EF, Serialization) specifically look for properties. 此外,许多依赖于反射(EF,序列化)的API专门寻找属性。

In the following part: 在以下部分中:

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

MyProp is a property . MyProp是一个属性 However, in this part: 但是,在这部分:

public class ReadOnly
{
    public readonly string MyProp;
}

MyProp is a field . MyProp是一个领域 These are two different things. 这是两件不同的事情。

is there a way to make an interface that works with both? 有没有办法使界面适用于两者?

No. Only properties can be put into interfaces. 不可以。只有属性可以放入接口。 Fields cannot. 字段不能。

One is a field ( readonly ); 一个是一个领域( readonly ); the other is a property. 另一个是财产。 Interfaces cannot define fields, only properties, methods, indexers and events. 接口不能定义字段,只能定义属性,方法,索引器和事件。

Both can only be assigned via constructor or field initialization, and cannot be changed thereafter. 两者都只能通过构造函数或字段初始化分配,并且此后不能更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM