C#getter vs readonly

时间:2014-09-27 19:38:54

标签: c#

以下是否有任何区别?

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

    // Two:
    public static int ValueAsAProperty { get { return 42; } }
}

我习惯以第一种方式编写常量(除非它们是私有/内部的,在这种情况下我使用const关键字),但我最近看到了第二种形式。

在可读性,约定,性能或其他方面,是否有任何优势?

9 个答案:

答案 0 :(得分:29)

您有三种选择:

  • public static readonly int Value = 42;
  • public static Value { get { return 42; } }
  • public const Value = 42;

如果值在运行时不会更改,但在未来的代码版本中可能会更改,请选择static readonly

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

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

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

该属性需要方法调用(调用getter是方法调用)。因此,如果值在运行时是常量,则不需要。

答案 1 :(得分:12)

是的,有一个优势:

如果值在将来的任何时候都可以更改(例如在代码的未来版本中),例如,在时间上,您可以在只读属性中支持改变你班级的公共界面。

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

答案 2 :(得分:7)

有两个主要区别:

第一个是字段不能在接口上,而属性可以。因此,如果要在界面中使用它,则必须使用该属性。

第二个更有趣的是,readonly字段可以被修改,而对象正在构建中。请使用以下代码:

public class MyTestClass
{
    public readonly int MyInt = 1;

    public MyTestClass()
    {
        MyInt = 2;
    }
}

如果来电者

new MyTestClass().MyInt

它们将得到2.对于静态readonly字段的静态构造函数也是如此。

答案 3 :(得分:3)

我看到它的方式,使用第一种方式更好地描述了价值的意图 - 这是不可变的。当一个人正在看课程时界面,他会看到该值是只读的,并且不必怀疑它是否可以在以后更改(因为在第二种情况下,他无法看到该属性的实现)。

关于const声明的重要注意事项(我不相信readonly的真实情况)是更改字段值会构成API更改即使您只是将值从42更改为41,也是如此。原因是对于consts,值是在编译期间确定的,这意味着如果我编译一个使用你的常量的模块,并且你以后更改它,我将仍然使用旧值,直到我重新编译我的模块与您的新版本。

答案 4 :(得分:2)

readonly很适合用于只能在构造函数中更改的内容。例如,当您遵循TDD模式时,典型服务作为接口。

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

readonly

const

干杯

答案 5 :(得分:1)

对我而言,主要优势在于readonly您可以在代码中的任何位置声明它。但是,您将有机会仅将其设置为一次。使用setter,您可以一次声明并设置。

答案 6 :(得分:1)

我认为第一行使用readonly关键字使某些内容保持不变或者只是readonly。

并且第二行使用属性来实现readonly。两者都做同样但如果你与IL比较,属性会在dll中添加几行额外的代码。

答案 7 :(得分:0)

一个属性只是一个围绕字段的语法糖,一个没有设置器的属性被简单地声明为 readonly 字段,因此编译器将允许您将其设置为运行时,因为对于编译器,您引用的是只读字段。关于使用什么字段或属性有更多的讨论,这不在问题的范围之内。是的,它是您必须进行@SOreadytohelp引用的重新编译的语法糖。为了清楚起见,属性是一个为其创建了get和set方法的字段,C#将允许您像一个 字段一样引用它,而不是每次都对getter或setter进行烦人的调用。 / p>

答案 8 :(得分:0)

是的,两者之间有区别。

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

可以随时在班级内设置一个{get; private set;}或简称为{get;}(简称)。

示例:

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