C#静态类vs结构预定义的string
一个同事刚刚在C#中创build了以下结构(示例代码被简化了)。 他的目标是缩短其余代码中所有预定义string的符号。
public struct PredefinedStrings { public const string VeryLongName = "Very Long Name"; public const string AnotherVeryLongName = "Another Very Long Name"; public const string TheLastVeryLongName = "The Last Very Long Name"; } public static void MethodThatUsesTheNames() { Console.WriteLine(PredefinedStrings.VeryLongName); Console.WriteLine(PredefinedStrings.AnotherVeryLongName); Console.WriteLine(PredefinedStrings.TheLastVeryLongName); }
虽然它似乎为他工作正常,我不能停止想知道他是否应该使用静态类,而不是一个结构,或者如果有更好的方法来实现这一点。
什么是这样做的首选方法? 请解释为什么。
使用struct
解决scheme,没有什么能够阻止一些其他的代码执行new PredefinedStrings()
,它不会做任何坏事 ,但它是在语义上混淆允许的。 使用静态类时,编译器将禁止为您创build。 不言而喻,静态类是在框架中提供常量的首选方式。
编辑添加,我说第二部分没有证据 – 我已经search并合理快速地findSystem.Net.Mime.DispositionTypeNames
和System.Net.WebRequestMethods.Http
。
我更喜欢string都在资源文件中,而不是embedded代码中 – 主要是出于国际化的原因。 然后可以通过一个静态类来访问这个属性成员的值。
除了一个static class
和struct
,为什么不考虑使用resource
文件的常量string? 这些可以像SomeNamespace.ResourceName.KeyName
非常容易地访问,并根据他们在你的项目中的位置可以外部pipe理,无需重新编译,如果需要的话…
简单的经验法则:直到没有别的select时才使用结构。
常量有两个缺点:
- 只能使用简单的types(string,数字等)
- 常量被注入到引用程序集中。 如果使用常量重新编译程序集,而不重新编译使用常量的程序集,则会遇到麻烦
我会写这样的代码(注意重命名重构):
public static class KnownNames { public static readonly string VeryLong = "Very Long Name"; public static readonly string AnotherVeryLong = "Another Very Long Name"; public static readonly string TheLastVeryLong = "The Last Very Long Name"; }
这段代码没有什么function上的错误。 但在风格上,我同意静态类更好。 静态类声明types的意图是只保存静态/常量数据。
这听起来像你正在寻找一个资源文件(.resx)。 这是存储这样的string的一个体面的地方,并且将您的string抽象成.resx文件将使未来本地化您的应用程序更加容易。 MSDN页面http://msdn.microsoft.com/en-us/library/1ztca10y.aspx是一个体面的开始更多的信息。;
不要忘记build议一个结构大小应该是大约16个字节。 给定一个32位系统,那就是4 System.String引用。 如果string的数量增加,我会说你最好用静态类。
我认为静态更好,这是我的推理。 如果这段代码驻留在某个库中,而另一段代码使用这个库,如果常量字段的值发生变化,那么这个库不仅需要重新编译(duh),而且还需要重新编译这个代码图书馆也是如此。 原因是,编译在引用它们的地方插入常量值。 如果你使用静态的,你不会有这个问题,因为你引用的字段不是值 。
静态类似乎是最好的方式去,因为它是最标准和预期的。 我认为结构/ const版本可能会更快,但经过一些testing,他们不是。
这里是我的快速testing的结果,包括长度,比较,concat,复制,indexOf和子串。 它是在没有附加debugging器的情况下在.Net 4.0中运行的。
.Net 3.0 .Net 4.0 static class with static read-only string: 0.217 0.364 seconds static class with const string: 0.211 0.361 seconds struct with static read-only string: 0.211 0.372 seconds struct with const string: 0.214 0.371 seconds Properties.Resources string: 1.173 1.268 seconds
除了使用比较慢的资源文件以外,它们都具有相同的性能。 虽然Properties.Resources较慢,但它不存储在可执行文件中,因此在某些情况下可能更合适。 所以使用“静态类”或Properties.Resources存储string在我看来。
除非这些结构符合本答案中详述的某些标准,否则通常会避免结构。
由于你的同事没有使用它来存储一个值,他应该使用一个类,而不是一个结构。
在我的实践中,我们使用Dictionary<enumNameType, string>
。 enumNameType是你可以拥有的不同types的名字(在你的情况下)…这个字典被包装在一个静态类中并被caching – 我们只是在第一次使用它时创build它,然后返回相同的对象…
我希望这对你也有用!
我也使用常量的结构,但只用于内部使用,而不是公共API。 因为枚举也转换为结构,所以感觉很自然。
一个简单的事实,就是你被允许创build一个新的对象,意图是一个常数,这是明显的不良习惯的证据(通常)。 我说“通常”,因为.NET确实偶尔使用这个概念,尽pipe它不清楚为什么。
当然,你总是可以做这样的事情:
public class Foo { public struct Bar { public static double A = 100; public Bar(double a) { A = a; } } }
这在技术上certificateBar
的创build是合理的; 然而,并不能保证常量Bar
是相同的(即使在单线程的环境中),最终几乎没有用处。