【问题标题】:Is is a good practice to store propery names in a public constant string?将属性名称存储在公共常量字符串中是一种好习惯吗?
【发布时间】:2011-10-05 01:42:41
【问题描述】:

为了保护我们自己免于因任何重命名属性而失败(假设您重新生成 poco 类,因为您更改了相关 Db 表中的一些列名)是 decalre 保留属性的常量字符串的好习惯吗?里面有名字吗?

public const string StudentCountPropertyName = "StudentCount";
public int StudentCount {get;set;}

例如:考虑一个DataBinding;在 DataFieldName 属性中显式键入属性名称。

或者这不是一个好主意,有更好更安全的方法吗?

【问题讨论】:

  • 您打算如何利用这些常量的存在?
  • 想象一下:DataFieldName=""

标签: c# .net data-binding constants strong-typing


【解决方案1】:

恕我直言,将任何“魔术字符串”移动到常量总是一个好主意。

您可以考虑使用 lambda 表达式来“挑选”您的属性,例如:

GetDataFieldName(studentCollection => studentCollection.Count)

您必须自己实现GetDataFieldName,使用一点反思。您可以查看来自 MVC 的 HtmlHelperExtensions 以了解它是如何完成的。这将是最安全的方法,它会在出现问题时为您提供编译时错误,并允许使用现有的重构工具轻松重命名属性。

【讨论】:

  • 如果属性被内联,有多安全?
  • @ValentinKuzub:内联不会改变方法的语义,因此不可能降低对象的安全性或可访问性。内联严格来说是一种 JIT 优化,作为程序员,您根本不应该关心这些。
  • 如果属性是内联的,基于反射的属性名称解析会失败,那是我的担心
  • @Valentin - if property is inlined reflection based property name resolution would fail - 你确定吗?我认为 IL 优化不会影响反射。
  • well inline property IL 优化意味着所有使用 int CountPropName{get{return m_Count;}} 属性都替换为'return m_Count;'如您所见,如果发生这种优化,CountPropName 将完全从优化的程序集中消失。你能保证你的属性不会被内联吗?
【解决方案2】:

从一个角度来看:如果您多次使用此属性名称,这是一种很好的做法。这肯定会有助于重构,例如,当您更改属性名称时,您会发现您也需要更改此 const。

从另一个角度来看,我想当我的具有 10 个属性的类将具有 10 个额外的 const 时,这将是丑陋的。如果您想避免 const 或显式名称输入,另一种解决方案是通过反射获取属性名称。

是否使用这种方法你应该自己决定。

【讨论】:

    【解决方案3】:

    我认为将这个“神奇的字符串”或“神奇的数字”放在某种强类型存储中是一种常见的做法。

    您可以考虑以面向方面的方式对其进行编码。

    例如,对 notifypropertychagned 的调用可以通过使用 aop 框架实现的属性来实现,例如 PostSharp

    [NotifyChange]
    public int Value {get;private set}
    

    此工具也有一些缺点,但我认为在某些情况下它们可以为您节省大量工作

    【讨论】:

      【解决方案4】:

      我不知道我是否完全理解你的问题,但如果我理解正确的话,我会为此使用一个属性,例如在 Linq 中使用 ColumnAttribute 用于将属性映射到特定列在数据库中 (http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.columnattribute.dbtype.aspx),如本例所示:

      [Column(Storage="ProductID", DbType="VarChar(150)", CanBeNull=False)]
      public string Id { get; set; }
      

      而且我永远不会使用 DataFieldName,我会将 DataBind 绑定到强类型对象(当然还会为使用上述属性的类创建一个接口,以便我将来可以轻松更改实现;))

      【讨论】:

        【解决方案5】:

        我想如果在很多地方都使用了这些名称,那么在这个地方更改它们并使用您评论中描述的常量会更容易。

        但是,更改数据库列名称和对象属性名称意味着更改您的概念数据模型。你认为这会多久发生一次?在项目的早期阶段,虽然概念建模和实现在整个开发团队中是并行的,但这可能是相当流畅的,但是一旦完成了初始概念建模(无论是以正式的有意识的方式还是只是有机地),它通常是相当流畅的像这样的基本情况不太可能发生变化。出于这个原因,我认为这样做是相对不寻常的,并且该技术只会在边缘情况下有效。

        【讨论】:

        • 再一次,常量并不意味着改变,就像以往一样。更改公共常量会破坏二进制兼容性
        • 非常正确,但这仅在运送“已发布”程序集时相关,即供第三方使用,他们可能会或可能不会在放入新版本的程序集后重新编译其代码。对于内部使用的程序集,更改常数是可行的。然而,我同意,这在某种程度上仍然是对“常数”概念的误用。
        【解决方案6】:

        当然。这是个好主意。

        顺便说一句,我认为这些东西可以更好地存储在应用程序设置中,因为您可以稍后通过覆盖这些设置在应用程序配置文件中定义这些东西。

        这样做可以避免在某些数据库、POCO 或任何更改时重新编译,并且在 Visual Studio 2010 等较新版本中,您可以告诉它生成具有“公共”可访问性的设置,您可以强烈分享-typed 设置与引用包含它们的程序集的任何程序集。

        在一天结束时,我会用DataBindingSettings.StudentCountPropertyName 而不是常量来更改您的代码。

        易于管理、更可重用和可读,就像“您使用其设置配置数据绑定”一样。

        查看此 MSDN 文章以了解有关应用程序设置的更多信息:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-14
          • 2012-11-30
          • 2019-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-09
          相关资源
          最近更新 更多