.NET 中的字符串初始化

本文关键字:初始化 字符串 NET | 更新日期: 2023-09-27 18:35:06

我可能错过了一些东西,但据我所知,字符串和字符串是别名,如字符串和字符串之间的差异中所述,因此字符串只是一个对象!

现在我不明白的是下面的代码如何初始化 String 的新对象?

string s="Hello World"

我可以对常规对象执行此技巧吗?

.NET 中的字符串初始化

如果你在你的代码中编译它们......它们是编译时常量......即代码从你编译的二进制文件中显式引用它们,当然在运行时加载到内存中。

如果你在运行时构造它们......就像从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";