【问题标题】:Finding the name of a particular property of a class from within the class in C# 3.5从 C# 3.5 中的类中查找类的特定属性的名称
【发布时间】:2011-01-17 05:53:31
【问题描述】:

给一个像下面这样的类,我怎样才能找到一个特定属性的名称?

public class Student
{
    public int Grade
    {
        get;
        set;
    }

    public string TheNameOfTheGradeProperty
    {
        get
        {
            return ????
        }
    }

    // More properties..    
}

所以我想从 TheNameOfTheGradeProperty 属性中返回字符串“Grade”。我问的原因是我不想使用硬编码字符串,而是使用 lambda 表达式或其他东西。

我怎样才能做到这一点?

【问题讨论】:

  • 除非您以某种方式引用要返回其名称的属性,否则这是不可能的,如果您这样做,您最好只使用硬编码的字符串。您可以使用反射,但目前对我来说似乎毫无意义。你有什么要求?
  • @johnc 有时在数据绑定时需要属性名称,并非所有重构工具在重命名属性时都会考虑字符串文字
  • @johnc ...除了下面显示如何在不使用硬编码字符串的情况下完成请求的答案。

标签: c# .net reflection properties propertyinfo


【解决方案1】:

可以使用表达式来查找属性的名称,使用简单的扩展方法,您可以在任何对象上使用它...如果您需要将其限制为一组对象,您可以应用通用约束在 T 上。希望这会有所帮助

public class Student
{
    public int Grade { get; set;}
    public string Name { get; set; }

    public string GradePropertyName
    {
        get { return this.PropertyName(s => s.Grade); }
    }

    public string NamePropertyName
    {
        get { return this.PropertyName(s => s.Name); }
    }
}

public static class Helper
{
    public static string PropertyName<T, TProperty>(this T instance, Expression<Func<T, TProperty>> expression)
    {
        var property = expression.Body as MemberExpression;

        if (property != null)
        {
            var info = property.Member as PropertyInfo;
            if (info != null)
            {
                return info.Name;
            }
        }

        throw new ArgumentException("Expression is not a property");
    }
}

【讨论】:

    【解决方案2】:

    你有一个很奇怪的要求。您是说您不想使用硬编码字符串,因为您希望 TheNameOfTheGradeProperty 在重构类时保持最新?如果是这样,这是一种奇怪的方法:

    public class Student
    {
        public int Grade { get; set; }
    
        public string TheNameOfTheGradeProperty
        {
            get
            {
                Expression<Func<int>> gradeExpr = () => this.Grade;
                MemberExpression body = gradeExpr.Body as MemberExpression;
                return body.Member.Name;
            }
        }
    }
    

    【讨论】:

      【解决方案3】:
      using System.Reflection;
      
      return typeof(Student).GetProperty("Grade").Name;
      

      但正如您所见,使用反射(以这种方式)并没有那么遥遥领先,因为“Grade”字符串仍然是硬编码的,这意味着在这种情况下,仅使用 return "Grade" 会更有效。


      我喜欢做的一件事是像这样创建并向成员添加自定义属性。 以下内容可让您不必使用硬编码字符串“Grade”。

      public class Student {
      
      // TAG MEMBER WITH CUSTOM ATTRIBUTE
      [GradeAttribute()]
      public int Grade
      {
          get;
          set;
      }
      
      public string TheNameOfTheGradeProperty
      {
          get
          {
              /* Use Reflection.
                 Loop over properties of this class and return the
                 name of the one that is tagged with the 
                 custom attribute of type GradeAttribute.
              */
          }
      }
      
      // More properties..    
      
      } 
      

      Creating custom attributes can be found here.

      【讨论】:

      • 看到这个答案我忍不住笑了。
      • @johnc:它是老式的,考虑到 3.x 的特性,它可能是对属性的错误使用,但它仍然是一个选项。虽然不是“最自豪的时刻”:)
      • 代码没有错,我只是对简单的返回“Grade”的奇妙混淆感到好笑。我确定他有一个要求,我只是现在不知道是什么
      猜你喜欢
      • 1970-01-01
      • 2019-03-29
      • 2012-01-08
      • 1970-01-01
      • 1970-01-01
      • 2016-06-07
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      相关资源
      最近更新 更多