C#getter vs readonly

C#getter vs readonly,c#,C#,以下两者之间有什么区别吗 class C { // One: public static readonly int ValueAsAMember = 42; // Two: public static int ValueAsAProperty { get { return 42; } } } 我习惯于以第一种方式编写常量(除非它们是私有/内部的,在这种情况下我使用const关键字),但我最近看到了第二种形式 在可读性、惯例、性能或其他方面,一种方式比另一种方式

以下两者之间有什么区别吗

class C
{
    // One:
    public static readonly int ValueAsAMember = 42;

    // Two:
    public static int ValueAsAProperty { get { return 42; } }
}
我习惯于以第一种方式编写常量(除非它们是私有/内部的,在这种情况下我使用const关键字),但我最近看到了第二种形式


在可读性、惯例、性能或其他方面,一种方式比另一种方式有任何优势吗?

是的,有一个优势:

如果该值在将来的任何时候(例如,在代码的未来版本中)都可以更改,例如,它与时间相关,则可以在只读属性中支持该值,而无需更改类的公共接口


如果必须用属性替换
只读
字段,则必须重新编译使用类的任何其他程序集。

我的主要优势在于
只读
允许您在代码中的任何位置声明它。但是,您将有机会只设置一次。使用setter,您可以一次完成声明和设置。

readonly
非常适合用于只能在构造函数中更改的内容。当您遵循TDD模式时,这是典型的服务接口示例

在您的示例中,
const
是最好的,毕竟它是一个常量


干杯

在我看来,使用第一种方式可以更好地描述价值的意图——它是不可变的。当一个人查看类的接口时,他将看到该值是只读的,并且不必怀疑以后是否可以更改它(因为在第二种情况下,他看不到属性的实现)


关于
const
声明,需要注意的一点很重要(我不认为
readonly
)是更改字段的值构成了API更改,即使您只是将值从
42
更改为
41
。原因是对于
consts
,该值是在编译时确定的,这意味着如果我编译了一个使用常量的模块,而您后来更改了它,在我用新版本重新编译模块之前,我仍将使用旧值。

我认为第一行使用readonly关键字将某些内容设置为常量,或者更确切地说是readonly


第二行是使用属性实现只读。两者的作用相同,但如果与IL进行比较,则该属性会向dll添加几行额外的代码。

您有三种选择:

  • 公共静态只读int值=42
  • 公共静态int值{get{return 42;}}
  • public const int Value=42
如果值在运行时不会更改,但在将来的代码版本中可能会更改,请选择“静态只读”

如果值在运行时可能更改,请选择属性。当然,如果使用给定的代码,它不会改变

如果该值实际上是一个在未来版本中甚至不会更改的常量(如
Math.PI
int.MinValue
),请选择
const
。当然,
const
的使用受到值类型的限制

const
static readonly
之间的区别在于调用站点上的
const
值将被替换。如果在将来的版本中更改
const
的值,则需要使用新值重新编译依赖于类的所有程序集


属性需要方法调用(调用getter是一种方法调用)。因此,如果该值在运行时保持不变,则不需要这样做。

有两个主要区别:

首先,字段不能位于接口上,而属性可以位于接口上。因此,如果要在接口中使用此属性,则必须使用该属性

第二,更有趣的是,在构建对象时,可以修改
只读
字段。以下面的代码为例:

public class MyTestClass
{
    public readonly int MyInt = 1;

    public MyTestClass()
    {
        MyInt = 2;
    }
}
如果有来电者

new MyTestClass().MyInt

他们将得到2。静态
只读
字段的静态构造函数也是如此。

属性只是字段周围的语法糖,没有setter的属性只是声明为只读字段,因此编译器将允许您在构造函数中的运行时对其进行设置,因为对于编译器,您引用的是一个只读字段。关于如何使用字段或属性有一个更大的讨论,这不在问题的范围之内。是的,这是一个语法糖,你必须重新编译@SOreadytohelp引用的代码。要明确的是,属性是一个为其创建了get和set方法的字段,C#将允许您像字段一样引用它,而不是每次都对getter或setter进行恼人的调用。

是的,两者之间有区别

只能在构造函数中设置
只读
字段

{get;private set;}
可以在类内随时设置

示例:

public class Car
{
    public readonly string Name;

    public string color {get; private set;}

    public Car()
    {
        Name = "Car";
        Color = "Red";
    }

    // will fail compilation
    public void ModifyName()
    {
        Name = "Subaru"
    }

    // perfectly ok
    public void ModifyColor()
    {
        Color = "Green"
    }
}

这可能不是一个好问题。但我还是会给出一个答案:使用
const
,它或多或少相当于您的第一行。第二行介绍了一个方法调用,它可能会被内联,但有什么意义呢?为什么不使用“const”?我唯一使用的
readonly
是在构造函数中设置它们,通常是TDD和designmode(WPF&SL)的接口。在本例中使用
const
和C#命名标准,而不是C/C++hehe;)@Crasher
const
在编译时在IL中被替换。假设有两个程序集A和B,程序集B引用程序集A的常量值。如果更改程序集A中的
const
值,但不使用新编译的版本更新程序集B,则在两个程序集之间的值不同的情况下,可能会出现奇怪的行为。这绝对是一个边缘案件,