存储程序使用的一组常量的最佳方法是什么?[关闭]


97

我的程序使用... stringints,doubles等各种常量。存储它们的最佳方法是什么?我不希望使用Enum,因为数据不是所有相同的类型,并且我想手动设置每个值。我应该将它们全部存储在一个空类中吗?或者,还有更好的方法?


18
您想要的任何方式-那就是您需要的方式。
圣哈辛托

Answers:


135

您可能将它们放在具有静态只读属性的静态类中。

public static class Routes
{
    public static string SignUp => "signup";
}

23
+1,但如果您可以将它们从资源文件中提取出来进行本地化则更好。
乔尔·科恩荷恩

17
似乎有些罗word-为什么不使用静态只读字符串?
空置

6
为什么只读而不是const?您无需在运行时设置该值,因此无需将它们设置为只读。
菲利普·华莱士

91
const的问题在于,针对const编译的任何程序集在编译时都将获取这些const的本地副本。因此,如果更改值,则还必须根据定义常量的程序集重新编译所有程序集-因此,使用只读路径通常更安全。使用属性而不是公共静态值,可以在将来需要时(例如,从本地化读取)灵活地添加一些编程逻辑,而无需将接口更改为常量值。
cfeduke

11
作为魔鬼的拥护者,我必须指出const的优点是可以在切换情况下使用它。
arviman

27

IMO使用充满常数的类对常数很好。如果它们偶尔会改变,我建议您在配置中使用AppSettings,并使用ConfigurationManager类。

当我有实际上从AppSettings或类似应用程序中提取的“常量”时,我仍然始终会有一个“常量”类,用于包装从配置管理器读取的内容。Constants.SomeModule.Setting不必直接诉诸ConfigurationManager.AppSettings["SomeModule/Setting"]于任何要消耗所述设置值的地方,这总是更有意义。

此设置的好处是,由于SomeModule可能是Constants文件中的嵌套类,因此您可以轻松地使用Dependency Injection将依赖项注入SomeModule直接注入依赖它的类中。您甚至还SomeModule可以ISomeModuleConfiguration在使用的代码的顶部提取接口,然后创建依赖关系,这将使您可以将依赖项与Constants文件解耦,甚至可能使测试变得更容易,尤其是如果这些设置来自AppSettings和您可以使用config转换来更改它们,因为这些设置是特定于环境的。


1
只是要补充一点:原因是在构建时,不会更新其他程序集中使用的常量。这意味着如果您具有AssemblyA和AssemblyB,并且B使用A中的常量,则该值将被复制而不是被引用,因此重新构建A不会更新B。这可能会导致奇怪的错误。
卡米洛·马丁

1
@CamiloMartin有很多方法可以解决此问题,您的“常量”可以只是静态只读以避免这种情况,或者正如我所说,如果它们在蓝色月亮中多次更改以使用ConfigurationManager,就可以避免这种情况。
克里斯·马里西奇

是的,我只是说这不仅仅是因为您应该使用静态只读,这是一个约定,而是因为它实际上可能会引起混乱。另外,ConfigurationManager的替代方法是资源文件-您只需添加名称中带有语言代码的另一个资源文件,您的代码即刻本地化。
卡米洛·马丁

问题是,当您从其他程序集中引用该程序集时,必须将值复制到其配置文件中
symbiont

@symbiont,您可以嵌入配置文件并从清单中读取它们,如果需要,可以共享作为第三方组件
Chris Marisic

19

我想做的是以下操作(但请务必仔细阅读以使用正确的常量类型):

internal static class ColumnKeys
{
    internal const string Date = "Date";
    internal const string Value = "Value";
    ...
}

阅读本文以了解为什么const可能不是您想要的。常量的可能类型为

  • const领域。如果值将来可能会更改,请不要跨程序集(publicprotected)使用,因为该值将在编译时在其他程序集中进行硬编码。如果更改该值,则旧值将由其他程序集使用,直到重新编译它们为止。
  • static readonly 领域
  • static 没有财产 set

1
如果跨多个程序集使用为什么为只读?
菲利普·华莱士

为什么静态只读在多个程序集中比const更有效?
马修

15
将常量值从源程序集复制到已编译的代码中。这意味着,如果必须更改const值,则必须根据新版本重新编译所有从属程序集。使用静态只读方式更安全,更方便。
cfeduke

6
const的好处在于它们可以在交换机中使用
knaki02 2013年

11

这是IMO的最佳方式。不需要属性或只读:

public static class Constants
{
   public const string SomeConstant = "Some value";
}

9
如果要使用const,则仅公开为内部。不要将const公开(即使您认为程序集不会在组织外部使用)。此外,属性还为您提供了编程的灵活性,可用于将来的扩展,而无需重新定义界面。
cfeduke

4

空的静态类是合适的。考虑使用多个类,以便最终获得一组不错的相关常量,而不是一个庞大的Globals.cs文件。

此外,对于某些int常量,请考虑以下符号:

[Flags]
enum Foo
{
}

因为这样允许将值当作flags对待


“考虑使用多个类,这样您最终会得到一组不错的相关常量,而不是一个庞大的Globals.cs文件。” 我相信这是最好的建议,这周围是否没有一些设计模式?我不知道名字,是吗?
greg

3

使用web.config或app.config的另一票。配置文件是常量(例如连接字符串等)的好地方。我宁愿不必查看源代码即可查看或修改这些类型的事物。从.config文件中读取这些常量的静态类可能是一个不错的折衷方案,因为它将使您的应用程序可以像使用代码中定义的那样访问这些资源,但仍可以使您灵活地将它们放在易于查看/可编辑的位置空间。


2
连接字符串不是常量,而是一个设置。可能OP 实际上也意味着设置,而不是常量,但是我看不到任何证据。
乔恩·斯基特

我不敢苟同。根据定义,字符串文字是常量。更改配置文件中的字符串大致等同于更改代码并重新编译。就使它不是一个常数?我不这么认为。
3Dave

2
@David-不正确。编译器不在乎配置文件中的值-在运行时读取。
菲利普·华莱士

@PhilipW我明白这一点。我的观点是(响应于Jon Skeet的评论),特定的连接字符串是一个常量,就像所有字符串文字一样。可以更改“常量”的事实-通过修改配置文件,让您的应用从所述配置文件中提取新值,或者通过更改代码中需要重新编译/部署的文字-使其成为“设置”。字符串本身是常量,而不管其容器如何。我理解并同意您的观点-这不是我在说什么。
3Dave

1
根据我的经验,在不可预见的将来的某个时刻,即使您认为一百万年内都不会改变,您的“恒定”价值也需要改变。我认为在.config文件中执行此操作比更改源代码要容易得多。最终一切都变成了背景。
NinjaBomb

1

是的,static class除了与特定类型有关的常量外,用于存储常量的a就可以了。


那正是我想要做的。我希望他们出现在他们所属的班级中。但我不想将它们添加到类中,因为常量会因我所从事的公司而异。我尚未找到有关扩展常数或属性的任何信息。但是我可能会放弃这个想法,因为当我序列化这些类时,我不希望它们显示为成员
symbiont

0

如果这些常量是服务引用或影响应用程序行为的开关,我会将它们设置为应用程序用户设置。这样,如果需要更改它们,则不必重新编译,您仍然可以通过静态属性类引用它们。

Properties.Settings.Default.ServiceRef

0

我建议使用静态只读的静态类。请在下面找到代码片段:

  public static class CachedKeysManager
    {
        public static readonly string DistributorList = "distributorList";
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.