65.9K
CodeProject 正在变化。 阅读更多。
Home

如同魔法,无需任何附加条件

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2013 年 2 月 22 日

CPOL

3分钟阅读

viewsIcon

16838

辅助工具替换魔法字符串属性名称。

好吧,有一个附加条件,依赖于LINQ.Expressions。

您可能熟悉在HtmlHelper扩展中使用Lambda表达式,作为摆脱魔法字符串的一种方法。例如,对于一个显示模板,您可以使用Html.Display("Message"),它依赖于魔法字符串 "Message",或者您可以使用Html.DisplayFor(m => m.Message),魔法字符串就消失了。

或者您可能使用过ExpressionHelper.GetExpressionText来替换视图中模型里的魔法字符串属性名称。ExpressionHelper.GetExpressionText有一个重载,它接受一个Lambda表达式并返回一个表示属性名称的string。 例如,ExpressionHelper.GetExpressionText(p => p.Name)将返回string "Name"。 我发现ExpressionHelper.GetExpressionText在测试UI层时很有用,我需要通过名称找到一个控件来检查它的值。

利用 Visual Studio

通过这种使用利用Lambda表达式的辅助工具来替换魔法字符串的技术,您可以在运行时、在错误发生之前,利用Visual Studio的IntelliSense和调试器来确保您获得正确的属性名称。

ExpressionHelper 是 Web.MVC 的一部分,但只从模型中获取属性名称,并且 HtmlHelper 也只在视图中工作。 您的应用程序可能还有其他部分可以使用与这些帮助程序相同的功能,并且您希望利用 Visual Studio IDE。 最好有一个助手能够安全、准确地将任何类的任何属性名称解析为 string,并且在应用程序中任何需要它的地方都可以使用,并且有 Visual Studio 帮助您使用它。

像这样的助手还有其他的变体,但我发现 Scott Millett 的 "Professional ASP.NET Design Patterns" 中有一个。 他称它为 PropertyNameHelper,并将其包含在他的查询基础设施命名空间中。 该助手需要 LINQ.Expressions 库。 他查询命名空间中的其他类使用 LINQ,因此他将其放在那里很有意义。 但我发现它在我的项目的其他领域也很有用。 一种用途是当我为验证例程创建业务规则时。 我的业务规则对象是列表,我用属性名称及其规则的 string 对填充这些列表。 我想确保获得正确的属性名称,而不是输入错误,所以我使用 PropertyNameHelper

我的 PropertyNameHelper 版本位于名为 Helpers 的命名空间中,我在其中保留其他通用实用程序,并且是一个具有名为 StringNameForstatic 方法的 static 类。

使用起来很容易

在您的项目中包含对 Helpers 命名空间的引用和 using,并且您的项目引用的任何类都可以由助手使用。 对于一个名为 Product 的类,它具有一个名为 Price 的属性,您将使用 PropertyNameHelper.StringNameFor<Product>(p => p.Price)" 来返回 string "Price"。 就这么简单。

IntelliSense 确保 Product 是一个有效的类,并且 Price 是一个有效的属性。 使用 PropertyNameHelper 意味着您将始终获得 "Price"。 您不会错误地获得 "Pirce"。 如果您将属性名称从 Price 更改为 Cost,您可以使用重构工具更新所有引用,从而使您的代码不那么脆弱和有错误。 在您的测试中使用这些助手也使它们不那么脆弱。

using System.Linq.Expressions; 

namespace Helpers
{
   public class PropertyNameHelper
   {
          public static string StringNameFor<T>(Expression<Func<T, object >> expression) 
          {
               var expr = expression.Body as MemberExpression; 
               if (expr == null) {
                    var u = expression.Body as UnaryExpression; 
                    expr = u.Operand as MemberExpression; 
               }
               return expr.ToString().Substring(expr.ToString().IndexOf(".") + 1); 
          }
     } 
}
© . All rights reserved.