【问题标题】:What's the best way to store a group of constants that my program uses? [closed]存储我的程序使用的一组常量的最佳方法是什么? [关闭]
【发布时间】:2010-12-15 23:48:55
【问题描述】:

我的程序使用了各种常量...string's、int's、double's 等...存储它们的最佳方式是什么?我不认为我想要一个Enum,因为数据不都是相同的类型,我想手动设置每个值。我应该将它们全部存储在一个空的类中吗?还是有更好的办法?

【问题讨论】:

  • 任何你想要的方式 - 这就是你需要的方式。

标签: c# constants


【解决方案1】:

IMO 使用一个充满常量的类对于常量来说是很好的。如果它们会偶尔更改,我建议在您的配置和 ConfigurationManager 类中使用 AppSettings。

当我有实际从 AppSettings 或类似内容中提取的“常量”时,我仍然会有一个包含来自配置管理器的读取的“常量”类。拥有Constants.SomeModule.Setting 而不是在任何想要使用所述设置值的地方直接求助于ConfigurationManager.AppSettings["SomeModule/Setting"] 总是更有意义。

此设置的加分项,因为SomeModule 可能是常量文件中的嵌套类,您可以轻松地使用依赖注入将SomeModule 直接注入到依赖它的类中。您甚至可以在SomeModule 之上提取一个接口,然后在您的消费代码中创建一个对ISomeModuleConfiguration 的依赖,这将允许您将依赖关系解耦到常量文件,甚至可能使测试更容易,特别是如果这些设置来自 AppSettings,您可以使用配置转换来更改它们,因为这些设置是特定于环境的。

【讨论】:

  • 只是补充一点:原因是当您构建时,从其他程序集中使用的常量不会更新。这意味着如果您有 AssemblyA 和 AssemblyB 并且 B 使用来自 A 的常量,则该值被复制,而不是被引用,因此重新构建 A 不会更新 B。这可能会导致奇怪的错误。
  • @CamiloMartin 有很多方法可以处理这个问题,你的“常量”可以只是静态只读来避免这种情况,或者正如我所说,如果他们在蓝月亮中多次更改以使用 ConfigurationManager。跨度>
  • 是的,我只是说这不仅仅是因为它是您应该使用静态只读的约定,而是因为它实际上可能会造成混乱。此外,ConfigurationManager 的替代方案是资源文件 - 您只需添加另一个名称中带有语言代码的资源文件,您的代码就会立即本地化。
  • 问题是当您从其他程序集引用此程序集时,您必须将值复制到它们的配置文件中
  • @symbiont 您可以嵌入配置文件并根据需要从清单中读取它们,以便作为第 3 方组件进行共享
【解决方案2】:

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

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

【讨论】:

  • +1,但如果您可以从资源文件中提取这些内容进行本地化,效果会更好。
  • 似乎有点罗嗦 - 为什么不是静态只读字符串?
  • 为什么只读而不是常量?您没有在运行时设置该值,因此无需将它们设置为只读。
  • const 的问题在于,针对 const 编译的任何程序集在编译时都会获得这些 const 的本地副本;因此,如果您更改一个值,您还必须重新编译所有依赖于定义常量的程序集的程序集 - 因此走只读路线通常更安全。属性而不是公共静态值使您可以灵活地在将来需要时添加一些编程逻辑(即从本地化中读取),而无需将接口更改为常量值。
  • 作为魔鬼的拥护者,我必须指出,使用 const 的优点是您可以在 switch case 中使用它。
【解决方案3】:

我喜欢做以下事情(但请确保阅读到最后以使用正确的常量类型):

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

Read this 了解为什么 const 可能不是您想要的。可能的常量类型是:

  • const 字段。如果值可能将来发生变化,请勿跨程序集使用(publicprotected),因为该值将在编译时在其他程序集中进行硬编码。如果更改该值,则其他程序集将使用旧值,直到重新编译它们。
  • static readonly 字段
  • static 没有 set 的属性

【讨论】:

  • 如果跨多个程序集使用,为什么只读?
  • 为什么静态只读比 const 更适用于多个程序集?
  • 常量值从源程序集中复制到编译后的代码中。这意味着如果您必须更改 const 值,则必须针对新版本重新编译所有依赖程序集。使用静态只读的更安全、更方便。
  • const的好处是可以在switch中使用
【解决方案4】:

一个空的静态类是合适的。考虑使用几个类,这样你就可以得到一组好的相关常量,而不是一个巨大的 Globals.cs 文件。

此外,对于某些 int 常量,请考虑以下表示法:

[Flags]
enum Foo
{
}

因为这允许treating the values like flags

【讨论】:

  • “考虑使用几个类,这样你就可以得到一组好的相关常量,而不是一个巨大的 Globals.cs 文件。”我相信这是最好的建议,难道没有一些设计模式吗?我不知道任何人的名字,是吗?
【解决方案5】:

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

【讨论】:

  • 这正是我想要做的。我希望他们以他们所在班级的成员的身份出现。但我不想将它们添加到类中,因为常量因我正在为之工作的公司而异。我还没有找到任何关于扩展常量或属性的信息。但我可能会放弃这个想法,因为我不希望他们在序列化这些类时显示为成员
【解决方案6】:

再次投票支持使用 web.config 或 app.config。配置文件是连接字符串等常量的好地方。我不想查看源代码来查看或修改这些类型的东西。从 .config 文件中读取这些常量的静态类可能是一个很好的折衷方案,因为它可以让您的应用程序访问这些资源,就好像它们是在代码中定义的一样,但仍然可以让您灵活地将它们放在易于查看/可编辑的位置空间。

【讨论】:

  • 连接字符串不是常量,而是设置。可能是 OP 真的 也意味着设置,而不是常量,但我没有看到任何证据。
  • 我不同意。根据定义,字符串文字是常量。更改配置文件中的字符串大致相当于在代码中更改并重新编译; that 会使它不是一个常数吗?我不这么认为。
  • @David - 不正确。编译器并不关心您在配置文件中的值 - 这是在运行时读取的。
  • @PhilipW 我明白这一点。我的观点是(回应 Jon Skeet 的评论)一个特定的连接字符串是一个常量,就像所有字符串文字一样。可以更改“常量”的事实 - 通过修改配置文件,让您的应用程序从所述配置文件中提取新值,或者通过更改需要重新编译/部署的代码中的文字 - 不会让它成为一个“设置”。无论其容器如何,字符串本身都是恒定的。我理解并同意你的观点——这不是我说的。
  • 根据我的经验,在不可预见的未来的某个时刻,你的“恒定”值将需要改变,即使你认为它永远不会在一百万年内发生。我认为这在 .config 文件中比更改源代码要容易得多。一切最终都成为一个设定。
【解决方案7】:

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

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

【讨论】:

  • 如果您要使用 const,请仅公开为内部。不要公开 const(即使您认为您的程序集不会在您的组织外部使用)。此外,属性为您提供了未来扩展的编程灵活性,而无需重新定义您的界面。
  • 对于真正不变的事物(例如数学常数)使用const 是可以的。当属性或值可能在不同版本的程序之间发生变化时,请使用readonly
【解决方案8】:

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

Properties.Settings.Default.ServiceRef

【讨论】:

    【解决方案9】:

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

      public static class CachedKeysManager
        {
            public static readonly string DistributorList = "distributorList";
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-03
      • 2014-04-11
      • 2016-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多