C# 静态类与预定义字符串的结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2223162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Static class vs struct for predefined strings
提问by Rob van Groenewoud
A co-worker just created the following construction in C# (the example code is simplified). His goal was to shorten the notation for all predefined strings in the rest of the code.
一位同事刚刚在 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);
}
Although it seems to work fine for him, I can't stop wondering whether he should have used a static class instead of a struct or if there's a more elegant way to achieve this.
尽管这对他来说似乎很好用,但我不禁想知道他是否应该使用静态类而不是结构体,或者是否有更优雅的方法来实现这一点。
What would be the preferred way to do this? Please also explain why.
这样做的首选方法是什么?还请说明原因。
采纳答案by AakashM
With the struct
solution, there's nothing to stop some other code doing new PredefinedStrings()
, which won't do anything bad, but is something it's semantically confusing to allow. With a static class the compiler will forbid creation for you. And it goes without saying that static class is the preferred way of providing constants in the Framework.
有了这个struct
解决方案,就没有什么可以阻止其他一些代码做的了new PredefinedStrings()
,这不会做任何坏事,但在语义上是令人困惑的。对于静态类,编译器将禁止为您创建。不用说,静态类是在框架中提供常量的首选方式。
editto add, I said that second part without evidence - I have since searched and reasonably quickly found System.Net.Mime.DispositionTypeNames
and System.Net.WebRequestMethods.Http
.
编辑补充一下,我在没有证据的情况下说第二部分 - 我已经搜索并合理地快速找到了System.Net.Mime.DispositionTypeNames
和System.Net.WebRequestMethods.Http
。
回答by anthares
In my practice for this purpose we use Dictionary<enumNameType, string>
. Where enumNameType is the different type of names you can have (in your case) ... This dictionary is wrapped in a static class and is cached - we create it just the first time we use it and then return the same object ...
在我为此目的的实践中,我们使用Dictionary<enumNameType, string>
. enumNameType 是您可以拥有的不同类型的名称(在您的情况下)......这个字典被包装在一个静态类中并被缓存 - 我们只是在第一次使用它时创建它然后返回相同的对象......
I hope this will be useful for you, too!
我希望这对你也有用!
回答by JaredPar
There is nothing functionally wrong with this code. But stylistically I agree a static class is better. A static class declares the intent of the type is to only hold static / constant data.
这段代码在功能上没有任何问题。但在风格上我同意静态类更好。静态类声明该类型的意图是仅保存静态/常量数据。
回答by Andrew
I would prefer the strings all being in a resource file and not embedded within the code - primarily for internationalisation reasons. This can then be accessed via a static class with the values as property members.
我希望所有字符串都在资源文件中而不是嵌入在代码中 - 主要是出于国际化的原因。然后可以通过将值作为属性成员的静态类访问它。
回答by KP.
Besides a static class
and struct
, why not consider using resource
files for constant strings? These can be accessed very easily as SomeNamespace.ResourceName.KeyName
, and depending on where they are located in your project can be managed externally without recompiling if need be...
除了 a static class
and struct
,为什么不考虑将resource
文件用于常量字符串?这些可以很容易地访问SomeNamespace.ResourceName.KeyName
,并且根据它们在项目中的位置可以在外部进行管理,而无需重新编译,如果需要...
回答by BFree
I think static is better and here's my reasoning. If this code lives in some library, and another piece of code consumes this library, if the value of the constant fields change, then not only will this library need to be recompiled (duh) but you'll have to recompile the code consuming this library as well. The reason for that is, the compile inserts the constant values wherever you reference them. If you use static though, you won't have this problem, as you're referencing the fieldnot the value.
我认为静态更好,这是我的推理。如果此代码存在于某个库中,而另一段代码使用此库,则如果常量字段的值发生变化,则不仅需要重新编译此库(废话),而且您还必须重新编译使用此库的代码图书馆也是。原因是,编译器会在您引用常量值的任何地方插入它们。但是,如果您使用 static ,则不会遇到此问题,因为您引用的是field而不是value。
回答by Max Toro
I use structs for constants too, but only for internal use, not for public APIs. It feels natural since enums are also converted to structs.
我也将结构体用于常量,但仅用于内部使用,而不用于公共 API。感觉很自然,因为枚举也被转换为结构。
回答by stack
It sounds like you're looking for a resource file (.resx). It's a decent place to store such strings, and abstracting your strings into a .resx will make it easier to localize your application in the future. The MSDN page at http://msdn.microsoft.com/en-us/library/1ztca10y.aspxis a decent start for more information.
听起来您正在寻找资源文件 (.resx)。这是存储此类字符串的好地方,将您的字符串抽象为 .resx 将使将来更容易本地化您的应用程序。位于http://msdn.microsoft.com/en-us/library/1ztca10y.aspx的 MSDN 页面是获取更多信息的不错起点。
回答by Jesse C. Slicer
Don't forget the recommendation that a struct size should be about 16 bytes. Given a 32-bit system, that's 4 System.String references right there. I'd say you're better off with a static class if the number of strings will increase.
不要忘记 struct 大小应该是大约 16 字节的建议。给定一个 32 位系统,那里有 4 个 System.String 引用。如果字符串的数量会增加,我会说你最好使用静态类。
回答by Konstantin Spirin
Simple rule of thumb: never use structs until you have no other choice.
简单的经验法则:除非别无选择,否则永远不要使用结构。
Constants have a couple of drawbacks:
常量有两个缺点:
- only simple types can be used (strings, numerics, etc.)
- constants are injected into referencing assemblies. If you recompile assembly with constants and don't recompile assembly that uses constants, you'll get into trouble
- 只能使用简单类型(字符串、数字等)
- 常量被注入到引用程序集中。如果你用常量重新编译程序集,而不重新编译使用常量的程序集,你会遇到麻烦
I would write your code like this (notice rename refactoring too):
我会像这样编写你的代码(注意重命名重构):
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";
}