2

以下两个声明之间的主要区别是什么?

public string Name
{
  get { return "Settings"; }
}

public const string Name = "Settings";

不是都防止被改变吗?

4

4 回答 4

9

第一个是仅提供 get 访问器的属性。这是按实例指定的。

第二个是编译时间常数。在编译时,它将被替换为"Settings",因此它根本不是该类型的成员。

const声明确实具有消除方法调用的优点(因为它只是一个编译时常量值),但是,属性调用可能会在运行时被 JIT 消除。

属性声明的优点是允许您稍后更改其工作方式,而不会破坏兼容性——甚至是二进制兼容性。为了查看 const 值的变化,需要对使用它的所有内容进行完全重新编译,即使它位于单独的程序集中。

基本上, apublic const可能是一个好主意,但前提是这是一个永远不会改变的值——不是在程序运行期间永远不会改变的值,而是永远不会在任何地方、任何时间改变的值。 Int32.MaxValue是一个很好的例子 - 这具有基于Int32类型本身的特定含义 - 这不可能改变。因此,作为public const. 在你的情况下,可能是你最终"Settings"想要改变的东西——如果是这样的话,那么将它封装在一个属性中是有意义的。

于 2012-10-19T17:07:50.217 回答
2

第一个是属性声明。第二个是实例变量声明。

两者都不能改变,但语义不同。就财产而言,没有任何改变。当您使用简写语法来声明属性 ( public string Name { get; }) 时,它会创建一个隐藏的实例变量来保存该属性的值,但是当您手动声明一个属性时,就像您在此处所做的那样,并且您不声明实例变量随之而来的是,没有要更改的数据。在给出的示例中,该属性不返回某些包含“设置”的变量的值,而是返回文字字符串。它与返回文字的方法几乎没有什么不同:它总是返回相同的值,但你不会将其称为“不可变”,因为“不可变”意味着有一些东西需要改变。

在实例变量的情况下,您正在创建一个属于该类的每个实例的字段。由于const,该字段的值不能被修改,但是存储了一个实际值,原则上可以修改,除非是const

于 2012-10-19T17:07:28.930 回答
2

const运行时不存在变量。该字段的值将在编译时放置在使用该字段的任何位置。无论在何处使用名称,它都与复制粘贴“设置”相同。

另一方面,运行时存在只读属性。这意味着该类型中存在一个新属性,以及相关的元数据。每次调用该属性时,它将调用 getter 的方法,涉及相关的调用堆栈操作,并且该方法将简单地返回相同的值。

当可以使用const字段时,通常最好使用字段。只读属性的优点是您可以返回不是编译时文字的内容。

于 2012-10-19T17:09:06.027 回答
1

不是都防止被改变吗?

是的,(仅)在这方面它们是相同的。

但是这个属性很不寻常,所以比较似乎是人为的。

public string Name
{
  get { return "Settings"; }
}

您通常不会将属性用于设计时常量。如果它在整个持续时间内确实是固定的,请使用您的第二个声明(常量,而不是属性):

public const string Name = "Settings";
于 2012-10-19T17:08:58.360 回答