以下两个声明之间的主要区别是什么?
public string Name
{
get { return "Settings"; }
}
和
public const string Name = "Settings";
两者都不能被改变吗?
答案 0 :(得分:9)
第一个是只提供get访问器的属性。这是指定每个实例。
第二个是编译时常量。在编译时,它将替换为"Settings"
,因此它根本不是该类型的成员。
const
声明确实具有消除方法调用的优势(因为它只是一个编译时常量值),但是,在运行时JIT可能会消除属性调用。
属性声明的优点是允许您在以后更改其工作方式,而不会破坏兼容性 - 甚至是二进制兼容性。为了查看const值的变化,需要对使用它的所有内容进行完全重新编译,即使它在单独的程序集中也是如此。
基本上,public const
可能是一个好主意,但前提是永远不会改变的值 - 不是在程序运行期间永远不会改变的值,但这在任何时候都不会改变。 Int32.MaxValue
是一个很好的例子 - 它具有基于Int32
类型本身的特定含义 - 这种情况无法改变。因此,它作为public const
是有意义的。在您的情况下,"Settings"
可能是您想要更改的内容最终 - 如果是这种情况,则将其封装在属性中是有意义的。
答案 1 :(得分:2)
第一个是财产声明。第二个是实例变量声明。
两者都不能改变,但语义不同。在财产的情况下,没有任何改变。当您使用简写语法声明属性(public string Name { get; }
)时,它会创建一个隐藏的实例变量来保存属性的值,但是当您手动声明属性时,就像在此处所做的那样,并且您不会声明一个实例变量与它一起使用,没有数据需要更改。在给出的示例中,属性不返回包含“Settings”的某个变量的值,它返回文字字符串。它与返回文字的方法没什么不同:它总是返回相同的值,但你本身并不称它为“不可变”,因为“不可变”意味着有一些东西需要变异。
对于实例变量,您正在创建属于该类的每个实例的字段。由于const
,字段的值无法修改,但存储的实际值原则上可以修改,但是const
。
答案 2 :(得分:2)
运行时不存在const
变量。在编译时,字段的值将被放置在使用该字段的任何位置。它与使用Name的任何地方的“设置”进行复制粘贴相同。
另一方面,只读属性存在于运行时。这意味着该类型中存在一个具有关联元数据的新属性。每次调用属性时,它都会调用getter的方法,涉及相关的调用堆栈操作,该方法只返回相同的值。
当可以使用const
字段时,通常会更好。只读属性的优点是可以返回不是编译时文字的东西。
答案 3 :(得分:1)
两者都不能被改变吗?
是的,(仅)在这方面他们是一样的。
但是这个属性很不寻常,所以这种比较似乎是人为的。
public string Name
{
get { return "Settings"; }
}
通常不会将属性用于设计时常量。如果它在整个持续时间内确实是固定的,请使用您的第二个声明(常量,而不是属性):
public const string Name = "Settings";