将成员与其字符串名称链接起来的最有效方法是什么?

Chr*_*kes 15 .net c#

.NET框架的各个部分需要使用属性的字符串名称:

  • ArgumentException 使用有问题的变量的名称
  • DependencyProperty 使用它支持的属性的名称
  • INotifyPropertyChanged 使用刚刚更改的属性的名称.

填充这些参数的最简单方法似乎是对它们进行硬编码(即:)new ArgumentNullException("myArg").这似乎过于脆弱,直到运行时才会发现你的重构破坏了关联.

使用反射来验证这些参数是跳出来的唯一解决方案但是说验证只在运行时执行.

是否有更好的方法来定义成员与其名称之间的关系?将优先考虑简单但优雅的设计时执行.

Jos*_* M. 1

您可以使用 anExpression<Func<T, object>>来执行此操作,如下所示:

using System;
using System.Linq;
using System.Linq.Expressions;

namespace ConsoleApplication3
{
    public class MyClass
    {
        public int IntegralValue { get; set; }

        public void Validate()
        {
            if (this.IntegralValue < 0)
                throw new ArgumentOutOfRangeException(PropertyHelper.GetName<MyClass>(o => o.IntegralValue));
        }
    }

    public static class PropertyHelper
    {
        /// <summary>Extracts the property (member) name from the provided expression.</summary>
        public static string GetName<T>(this Expression<Func<T, object>> expression)
        {
            MemberExpression memberExpression = null;

            if (expression.Body is MemberExpression)
                memberExpression = (MemberExpression)expression.Body;
            else if (expression.Body is UnaryExpression)
                memberExpression = (((UnaryExpression)expression.Body).Operand as MemberExpression);

            if (memberExpression == null)
                throw new ApplicationException("Could not determine member name from expression.");

            return memberExpression.Member.Name;
        }
    }

    public static class Program
    {
        public static void Main(string[] args)
        {
            MyClass good = new MyClass() { IntegralValue = 100 };
            MyClass bad = new MyClass() { IntegralValue = -100 };

            try { good.Validate(); }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            try { bad.Validate(); }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            Console.ReadKey();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: IntegralValue
    at ConsoleApplication3.MyClass.Validate() in d:\...\ConsoleApplication3\Program.cs:line 14
    at ConsoleApplication3.Program.Main(String[] args) in d:\...\ConsoleApplication3\Program.cs:line 50
Run Code Online (Sandbox Code Playgroud)

解释

这将允许您使用 lambda 来引用属性名称。该GetName方法检查提供的表达式并提取您指定的成员的名称。这样,当您重命名属性并重构更改时,所有这些 lambda 都会自动更新。不再需要任何绳子!