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;)@Crasherconst
在编译时在IL中被替换。假设有两个程序集A和B,程序集B引用程序集A的常量值。如果更改程序集A中的const
值,但不使用新编译的版本更新程序集B,则在两个程序集之间的值不同的情况下,可能会出现奇怪的行为。这绝对是一个边缘案件,