一位同事刚刚在C#中创建了以下构造(简化了示例代码)。他的目标是缩短其余代码中所有预定义字符串的表示法。
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);
}
虽然它似乎对他来说很好,但我不禁想知道他是否应该使用静态类而不是结构,或者是否有更优雅的方法来实现这一点。
这样做的首选方法是什么?还请解释原因。
答案 0 :(得分:42)
使用struct
解决方案,没有什么可以阻止其他代码执行new PredefinedStrings()
,这不会做任何不好的事情,但是它在语义上容易让人困惑。对于静态类,编译器将禁止为您创建。毫无疑问,静态类是在框架中提供常量的首选方式。
编辑添加,我说第二部分没有证据 - 我已经搜索过并且合理地快速找到System.Net.Mime.DispositionTypeNames
和System.Net.WebRequestMethods.Http
。
答案 1 :(得分:31)
我希望字符串全部存在于资源文件中而不是嵌入代码中 - 主要是出于国际化原因。然后可以通过静态类访问它,其值为属性成员。
答案 2 :(得分:25)
除了static class
和struct
之外,为什么不考虑将resource
文件用于常量字符串?这些可以像SomeNamespace.ResourceName.KeyName
一样轻松访问,并且根据项目的位置,可以在外部进行管理,无需重新编译,如果需要...
答案 3 :(得分:9)
简单的经验法则:在你别无选择之前,不要使用结构。
常量有几个缺点:
我会像这样编写你的代码(注意重命名重构):
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";
}
答案 4 :(得分:6)
听起来你正在寻找一个资源文件(.resx)。这是一个存储这些字符串的好地方,将字符串抽象为.resx将使您将来更容易本地化您的应用程序。 http://msdn.microsoft.com/en-us/library/1ztca10y.aspx的MSDN页面是一个不错的开始,可以获得更多信息。
答案 5 :(得分:5)
此代码没有任何功能上的错误。但风格上我同意静态类更好。静态类声明该类型的意图是仅保存静态/常量数据。
答案 6 :(得分:5)
不要忘记建议结构大小应该是大约16个字节。给定一个32位系统,那就是4个System.String引用。如果字符串的数量增加,我会说你最好使用静态类。
答案 7 :(得分:2)
除非符合this answer中详述的某些标准,否则通常会避免使用结构。
由于您的同事没有使用它来存储值,因此他应该使用类,而不是结构。
答案 8 :(得分:1)
我认为静态更好,这是我的推理。如果此代码存在于某个库中,而另一段代码使用此库,则如果常量字段的值发生更改,则不仅需要重新编译此库(duh),而且还必须重新编译使用此代码的代码图书馆也是如此。原因是,编译在您引用它们的任何地方插入常量值。如果您使用静态,则不会出现此问题,因为您引用的是字段而不是值。
答案 9 :(得分:1)
静态类似乎是最好的方法,因为它是最标准和预期的。我认为struct / const版本可能更快,但经过一些测试后却没有。
以下是我的快速测试结果,包括length,compare,concat,copy,indexOf和Substring。它是在没有附带调试器的版本的.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.Resource。
答案 10 :(得分:0)
在我的实践中,我们使用Dictionary<enumNameType, string>
。其中enumNameType是您可以拥有的不同类型的名称(在您的情况下)...此字典包含在静态类中并被缓存 - 我们在第一次使用它时创建它然后返回相同的对象...
我希望这对你也有用!
答案 11 :(得分:0)
我也使用结构作为常量,但仅供内部使用,不适用于公共API。由于枚举也被转换为结构,因此感觉很自然。
答案 12 :(得分:0)
允许您创建一个旨在成为常量的新对象的简单事实是不良做法的明显证据(通常)。我说&#34;通常&#34;因为.NET确实偶尔会使用这个概念,但目前还不清楚为什么。
当然,你可以随时做这样的事情:
public class Foo
{
public struct Bar
{
public static double A = 100;
public Bar(double a)
{
A = a;
}
}
}
在技术上证明创建Bar
是合理的;但是,不能保证常量Bar
永远不会相同(即使在单线程环境中),并且最终没什么用处。