.net 为什么不是';t字符串。是否为常数?
在.NET中,.net 为什么不是';t字符串。是否为常数?,.net,string,readonly,constants,.net,String,Readonly,Constants,在.NET中,String.Empty为什么是只读的而不是常量?我只是想知道是否有人知道这个决定背后的原因。这个答案是出于历史目的而存在的 原版: 因为String是一个类,因此不能是常量 扩展讨论: 在审查这一答案时,大量有用的对话被敲定,而不是将其删除,而是直接复制以下内容: 在.NET中,(与Java不同)字符串和字符串完全相同。是的,您可以在.NET中使用字符串文字常量–DrJokepu 2009年2月3日16:57 你是说一个类不能有常数吗吝啬鬼杰克2009年2月3日16:58 是的,
String.Empty
为什么是只读的而不是常量?我只是想知道是否有人知道这个决定背后的原因。这个答案是出于历史目的而存在的
原版:
因为String
是一个类,因此不能是常量
扩展讨论:
在审查这一答案时,大量有用的对话被敲定,而不是将其删除,而是直接复制以下内容:
在.NET中,(与Java不同)字符串和字符串完全相同。是的,您可以在.NET中使用字符串文字常量–DrJokepu 2009年2月3日16:57
你是说一个类不能有常数吗吝啬鬼杰克2009年2月3日16:58
是的,对象必须使用只读。只有结构可以执行常量。我认为当您使用string
而不是string
时,编译器会将常量更改为只读。所有这些都是为了让C程序员开心加里·舒特勒2009年2月3日16:59
tvanfosson只是解释得更详细一点。“X不能是常数,因为包含Y的是一个类”与上下文无关;)-利奥尼达斯2009年2月3日17:01
string.Empty是一个静态属性,返回string类的实例,即空字符串,而不是string类本身tvanfosson 2009年2月3日17:01
Empty是String类的只读实例(不是属性)senfo 2009年2月3日17:02
头部受伤。我仍然认为我是对的,但现在我不太确定了。今晚需要进行研究!——加里·舒特勒2009年2月3日17:07
空字符串是string类的一个实例。Empty是String类上的一个静态字段(不是属性,我已更正)。基本上就是指针和它指向的东西之间的区别。如果不是只读的,我们可以更改空字段引用的实例tvanfosson 2009年2月3日17:07
加里,你不需要做任何研究。想想看。字符串是一个类。Empty是字符串的一个实例senfo 2009年2月3日17:12
有一点我不太明白:String类的静态构造函数究竟如何创建String类的实例?这不是某种“鸡还是蛋”的情景吗DrJokepu 2009年2月3日17:12
五,
这个答案几乎适用于除System.String之外的任何其他类。NET为字符串做了很多性能特殊的大小写,其中之一是可以有字符串常量,只要试试就可以了。在这种情况下,杰夫·耶茨给出了正确的答案Joel Mueller 2009年2月3日19:25 如§7.18所述,常量表达式是可在编译时完全计算的表达式。由于创建除字符串以外的引用类型的非null值的唯一方法是应用新运算符,并且由于常量表达式中不允许使用新运算符,因此除字符串以外的引用类型的常量的唯一可能值为null。前两条评论直接取自C语言规范,并重申了Joel Mueller提到的内容senfo 2009年2月4日15:05 五,
使用
static readonly
而不是const
的原因是与非托管代码一起使用,如Microsoft在中所示。要查看的文件是sscli20\clr\src\bcl\system\string.cs
Empty常量保存空值
字符串值。我们需要打电话给警察
字符串构造函数,以便
编译器不会将此标记为
文字
将此标记为文字将意味着
它没有显示为字段
我们可以从本地访问它
我从中找到了这些信息。我认为这里有很多混乱和糟糕的反应 首先,
const
字段是静态
成员(不是实例成员)
检查C语言规范第10.4节常量
即使考虑了常数
静态成员,一个常量声明
既不需要也不允许静态
修饰语
如果<代码>公共const 成员是静态的,则不能考虑常量将创建新对象。
public static readonly string Empty = "";
public const string Empty = "";
鉴于此,以下代码行在创建新对象方面做了完全相同的事情
public static readonly string Empty = "";
public const string Empty = "";
以下是Microsoft的一条说明,解释了2之间的区别:
readonly关键字不同于
const关键字。常量字段可以
只能在声明时初始化
这场比赛的最后一场。可以创建只读字段
在声明中初始化
或者在构造函数中。所以,,
只读字段可以具有不同的
值取决于构造函数
用过。此外,常量字段是
编译时常量,只读
字段可用于运行时
常数
所以我发现这里唯一合理的答案是杰夫·耶茨的
String.Empty read only instead of a constant?
如果将任何字符串设为常量,则编译器将被替换为实际字符串,无论您在哪里调用它,您都将使用相同的字符串填充代码,并且当代码运行时,还需要从不同的内存数据中反复读取该字符串
如果将字符串保留在一个位置上,因为它是字符串.Empty
,则程序只在一个位置上保留相同的字符串并读取它,或引用它-将内存中的数据保持在最小值
另外,如果您使用字符串.Empty作为const编译任何dll,并且由于任何原因字符串.Empty发生了更改,那么编译后的dll将不再工作,因为成本
使内部代码在每次调用时实际保留字符串的副本
请参见以下代码示例:
public class OneName
{
const string cConst = "constant string";
static string cStatic = "static string";
readonly string cReadOnly = "read only string";
protected void Fun()
{
string cAddThemAll ;
cAddThemAll = cConst;
cAddThemAll = cStatic ;
cAddThemAll = cReadOnly;
}
}
编译器将以以下形式提供:
public class OneName
{
// note that the const exist also here !
private const string cConst = "constant string";
private readonly string cReadOnly;
private static string cStatic;
static OneName()
{
cStatic = "static string";
}
public OneName()
{
this.cReadOnly = "read only string";
}
protected void Fun()
{
string cAddThemAll ;
// look here, will replace the const string everywhere is finds it.
cAddThemAll = "constant string";
cAddThemAll = cStatic;
// but the read only will only get it from "one place".
cAddThemAll = this.cReadOnly;
}
}
大会电话
cAddThemAll = cConst;
0000003e mov eax,dword ptr ds:[09379C0Ch]
00000044 mov dword ptr [ebp-44h],eax
cAddThemAll = cStatic ;
00000047 mov eax,dword ptr ds:[094E8C44h]
0000004c mov dword ptr [ebp-44h],eax
cAddThemAll = cReadOnly;
0000004f mov eax,dword ptr [ebp-3Ch]
00000052 mov eax,dword ptr [eax+0000017Ch]
00000058 mov dword ptr [ebp-44h],eax
编辑:Corre