C#Static class vs struct用于预定义字符串

Rob*_*oud 50 c# string struct static-classes

一位同事刚刚在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);
}
Run Code Online (Sandbox Code Playgroud)

虽然它似乎对他来说很好,但我不禁想知道他是否应该使用静态类而不是结构,或者是否有更优雅的方法来实现这一点.

这样做的首选方法是什么?还请解释原因.

Aak*_*shM 44

使用该struct解决方案,没有什么可以阻止其他代码执行new PredefinedStrings(),这不会做任何坏事,但是它在语义上容易让人感到困惑.对于静态类,编译器将禁止为您创建.毫无疑问,静态类是在框架中提供常量的首选方式.

编辑添加,我说第二部分没有证据 - 我已经搜索并合理地快速找到System.Net.Mime.DispositionTypeNamesSystem.Net.WebRequestMethods.Http.

  • 这可能就是为什么使用结构体一开始让我皱眉的原因,但我没有想到检查“约定”。感谢您的提醒。这个答案对于在结构体和静态类之间进行选择非常有用,并且可能足以完成这项工作。但是,我必须检查使用资源文件是否适合这里。 (2认同)

And*_*rew 31

我希望字符串都在资源文件中,而不是嵌入代码中 - 主要是出于国际化的原因.然后可以通过静态类访问它,其值为属性成员.

  • 有趣的是,我早于这个回答说了同样的事情..我的upvotes在哪里?:P (3认同)
  • 在这种情况下,我们非常确定字符串不会改变,使用资源文件似乎对于这种特殊情况有点过分.静态类将完成这项工作(目前).但是我会记住这一点以备将来使用.谢谢! (3认同)
  • +1,这就是答案.而且不仅仅是国际化,而且使用资源文件可以让您纠正错误或更新字符串,而无需重新构建整个应用程序. (2认同)

KP.*_*KP. 25

除了static classstruct,为什么不考虑使用resource文件作为常量字符串?这些可以很容易地访问SomeNamespace.ResourceName.KeyName,并且根据它们在项目中的位置可以在外部进行管理而无需重新编译(如果需要)...


Kon*_*rin 11

简单的经验法则:在没有其他选择之前,不要使用结构.

常量有几个缺点:

  • 只能使用简单类型(字符串,数字等)
  • 常量被注入到引用程序集中.如果使用常量重新编译程序集并且不重新编译使用常量的程序集,则会遇到麻烦

我会像这样写你的代码(注意重命名重构):

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";
}
Run Code Online (Sandbox Code Playgroud)

  • 要解释为什么使用'static readonly'而不是const?Const将在编译时进行评估,这对于预期用途是合适的. (3认同)
  • 我列出了const缺点:仅限简单类型和编译值.如果您100%确定它不会改变,请使用const(例如Math.Pi) (2认同)

sta*_*ack 6

听起来你正在寻找一个资源文件(.resx).这是一个存储这些字符串的好地方,将字符串抽象为.resx将使您将来更容易本地化您的应用程序.有关更多信息,请访问http://msdn.microsoft.com/en-us/library/1ztca10y.aspx上的MSDN页面.


Jar*_*Par 5

这段代码没有任何功能上的错误.但风格上我同意静态类更好.静态类声明该类型的意图是仅保存静态/常量数据.


Jes*_*cer 5

不要忘记结构大小应该是大约16个字节的建议.给定一个32位系统,那就是4个System.String引用.如果字符串的数量增加,我会说你最好使用静态类.


Sun*_*est 5

静态类似乎是最好的方法,因为它是最标准和最期望的。我认为 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
Run Code Online (Sandbox Code Playgroud)

除了使用资源文件时速度较慢之外,它们的性能均相同。虽然 Properties.Resources 速度较慢,但​​它不存储在可执行文件中,因此在某些情况下可能更合适。因此,在我看来,使用“静态类”或 Properties.Resources 存储字符串。