.NET 中的字符串初始化
本文关键字:初始化 字符串 NET | 更新日期: 2023-09-27 18:35:06
我可能错过了一些东西,但据我所知,字符串和字符串是别名,如字符串和字符串之间的差异中所述,因此字符串只是一个对象!
现在我不明白的是下面的代码如何初始化 String 的新对象?
string s="Hello World"
我可以对常规对象执行此技巧吗?
如果你在你的代码中编译它们......它们是编译时常量......即代码从你编译的二进制文件中显式引用它们,当然在运行时加载到内存中。
如果你在运行时构造它们......就像从char数组一样,我猜CLR有必要的实现来做到这一点。例如 - 查看以下代码 http://referencesource.microsoft.com/#mscorlib/system/string.cs,97ccd50b20126543
[System.Security.SecuritySafeCritical] // auto-generated
private static String ConcatArray(String[] values, int totalLength) {
String result = FastAllocateString(totalLength);
int currPos=0;
for (int i=0; i<values.Length; i++) {
Contract.Assert((currPos <= totalLength - values[i].Length),
"[String.ConcatArray](currPos <= totalLength - values[i].Length)");
FillStringChecked(result, currPos, values[i]);
currPos+=values[i].Length;
}
return result;
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static String FastAllocateString(int length);
从本质上讲,字符串在语言中得到了特殊的处理,尽管它们是对象(不可变的),但您的理解是正确的,即它们不是使用传统意义上的new
运算符实例化的。 即您不按照您在评论中所说的去做String s=new String("Hello World");
因为如果您考虑一下,new
是多余的,因为您已经在双引号中将字符串定义为字符串文字。
因此,虽然您可以使用隐式运算符,但将字符串转换为给定类型。这不是同样的伎俩。字符串的诀窍是来自 CLR 的本机支持。
编辑:这是另一个证据..有一个特殊的IL OpCode来加载字符串。OpCodes.Ldstr
"将新对象引用推送到存储在元数据中的字符串文本。"
如果您查看已编译的代码,您会看到ldstr
操作码用于加载字符串,而不是newobj
操作码。
正如@KirkWoll所提到的,从使用转换运算符中,您可以使用隐式运算符
类似的东西
public class FOO
{
private string _foo;
public static implicit operator FOO(string foo)
{
FOO f = new FOO {_foo = foo};
return f;
}
}
然后调用它
FOO bar = "TADA";