在.Net中的struct String会有好处吗?

时间:2010-11-04 16:10:12

标签: .net string value-type reference-type

注意:这是一个假设的讨论。我实际上并不想实现struct String。

.Net String类可以是值类型(结构),因为它是不可变的并且成员很少。但String不是值类型。可能是因为String是在引入可空类型之前设计的,或者可能是为了匹配Java字符串的行为。

将String更改为值类型或实现String的值类型变体是否有益?它将删除一个间接级别并匹配常见的非可空案例。

4 个答案:

答案 0 :(得分:7)

简答

字符串具有以具有引用类型成员(例如,char[])以便具有可变大小。因此,任何struct String类型实际上只是伪装成值类型的引用类型。


中等答案

我更深入地讨论了这个问题here。但我的想法的基本要点是:是的,你可能有一个字符串“值类型”,大概是这样的:

public struct String
{
    char[] m_characters;

    public String(IEnumerable<char> characters)
    {
        m_characters = characters.ToArray();
    }

    public char this[int index]
    {
        get { return m_characters[index]; }
    }

    // All those other string functions... IndexOf, Substring, etc.
}

......但实在没有意义。上面的内容实际上只是一个嵌套在shell中的引用类型(围绕char[]的包装器),看起来像一个值类型。此外,当您以这种方式设计类型时,您会遇到使用值类型(例如,拳击的潜力)而没有任何好处的缺点(上述String类型的实例具有与以下相同的内存分配要求它包装的参考类型,所以它从GC的角度来看也没有任何东西。)

答案 1 :(得分:3)

没有。 .Net中的值类型必须在编译时具有已知的大小。 string的大小通常仅在运行时确定,因此不能作为值类型进行建模。

另外,.Net中的类型是Value类型,只能有1个大小。或者更简单地说,不同大小的相同值类型的不同实例。这意味着您需要将不同长度的字符串表示为不同类型。例如,"dog""zebra"将是不同的不兼容类型

注意

似乎这个问题可以用两种方式解释

  1. 使string成为没有备用存储空间的值类型
  2. 使string成为值类型并允许在数组中进行备用存储
  3. 我的答案是针对情景#1。看起来场景#2似乎没有很多价值,因为它只是用具有嵌入式引用类型的值类型替换引用类型。

答案 2 :(得分:2)

这确实是一种有效的实施方式。

非常天真,它看起来像这样:

struct String {
    readonly char[] _buffer;
    // Methods etc. …
}

string类相比,有一个特点(除了它不能是null之外):零大小的字符串不是以空值终止的!据我所知,.NET字符串 以空值终止,以便与旧版C API(WinAPI)进行交互。

有一点,字符串类有一个优点:实习可以更容易实现:String.Intern是一种构建器函数,给定相同的字符串值,总是返回相同的string实例。这样,两个实习字符串ab的比较可以大大加快:现在足以测试它们的地址。

但是,当然,通过比较字符串结构是否共享相同的地址,可以为字符串结构实现类似的字符串实习。

答案 3 :(得分:0)

没有。任何给定类型的结构总是具有相同的长度。字符串的不同实例不会。