我需要存储一个语言代码字符串,例如“en”,它始终包含2个字符。
把类型定义为"String"还是"Char"更好?
private string languageCode;
vs
的翻译是:vs。private char[] languageCode;
还有其他更好的选择吗?
这两个变量在内存中是如何存储的?当值被分配时,会分配多少字节或位?
我需要存储一个语言代码字符串,例如“en”,它始终包含2个字符。
把类型定义为"String"还是"Char"更好?
private string languageCode;
vs
的翻译是:vs。private char[] languageCode;
还有其他更好的选择吗?
这两个变量在内存中是如何存储的?当值被分配时,会分配多少字节或位?
存储方式
string
和char[]
都存储在堆上-因此存储方式是相同的。在内部,我会认为string
只是char[]
的封装,具有大量额外的代码使其对您有用。
另外,如果有许多重复的字符串,您可以利用托管池来减少这些字符串的内存占用。
更好的选择
我更喜欢使用string
- 它立即更清晰地显示数据类型及其使用方法。人们也更习惯使用字符串,因此可维护性不会降低。您还将从为您完成的所有样板代码中获得很大的益处。Microsoft还付出了很多努力,以确保string
类型不会成为性能障碍。
分配大小
我不知道分配了多少,但我相信字符串非常高效,因为它们仅分配足以存储Unicode字符的空间-由于它们是不可变的,因此这样做是安全的。另外,数组无法重新调整大小而不分配新数组中的空间,因此我会再次假设它们仅获取所需内容。
替代方案
根据您的信息,只有20个语言代码且性能至关重要,因此您可以声明自己的枚举以减少表示代码所需的大小:
enum LanguageCode : byte
{
en = 0,
}
char
所需的4个以上。但是这限制了可用的LanguageCode
值的范围为byte
的范围——对于20个项目来说,这足够大了。sizeof(LanguageCode)
操作符可以查看值类型的大小。枚举本质上只是底层类型,它们默认为int
,但是如您在我的代码示例中所见,可以通过“继承”新类型来更改默认类型。简短回答:使用字符串
详细回答:
private string languageCode;
private char[] languageCode;
这段文字将会被存储为字符数组,也就是说,一个Array对象将会被创建在堆上并被用于管理你的字符。但它仍然有一个长度属性,该属性存储在内部,因此与字符串相比,没有明显的内存节省。尽管一个数组可能比一个字符串简单,并且可能具有较少的内部变量,从而提供较低的内存占用(这需要验证)。
但另一方面,您失去了在这个字符数组上执行字符串操作的能力。甚至像字符串比较这样的操作现在都变得麻烦了。所以,长话短说,还是使用字符串吧!
// Option 1
class MyClass
{
char Char1, Char2;
}
// Option 2
class MyClass
{
CharStruct chars;
}
...
struct CharStruct { public char Char1; public char Char2; }
MyClass
在 32 位机器上每个实例将使用 8 字节加上 4 字节的字符。
// Option 3
class MyClass
{
CharStruct[] chars;
}
这将使用8个字节作为MyClass的开销,再加上4个字节用于chars
的引用,再加上12个字节用于数组的开销,再加上每个数组中CharStruct
所需的4个字节。
字符串确实有一个指针长度的大小开销,即32位进程为4个字节,64位进程为8个字节。但是,与字符数组相比,字符串提供了更多的功能。
如果您的应用程序使用许多短字符串,并且您不需要经常使用它们的字符串属性和方法,那么您可能可以节省一些内存空间。但是,如果您想将任何一个字符串用作字符串,您首先必须创建一个新的字符串实例。我无法看出这如何帮助您节省足够的内存以值得麻烦。
String只是在内部实现了一个char类型的索引器,可以说string
就相当于具有大量额外代码使其对您有用的char[]
类型,因此像数组一样,它总是存储在堆上。
如果不分配新空间,则无法操作数组,字符串也是如此,因此它是不可变的。
String实现了IEnumerable<char>
值得注意的一点:当您将字符串传递给函数时,它是按值传递,除非使用ref
struct Char2
{
public char C1, C2;
}
struct LanguageCode
的结构体是一个不错的选择。 - Adam Houldsworth
enum LanguageCode : short
并节省 2 个字节呢? - Adam Houldsworthbyte
,它只占用1个字节。我已经更新了我的答案。枚举是值类型,在方法作用域内存在于堆栈上,或者在类作用域内的堆空间中存在。 - Adam Houldsworth