2011-08-30 59 views
2

在C#中,如何使用反射来获取没有getter/setters的变量?例如,下面的getValue方法适用于d2,但不适用于d1。C#获取反射域

public class Foo { 

    public String d1; 
    public String d2 { get; set; } 

    public object getValue(String propertyName){ 
     return this.GetType().GetProperty(propertyName).GetValue(this, null); 
    } 
} 
+7

如果他们没有getter或setters,他们不是属性。他们是田野。他们不是一回事。 –

回答

9

d1不是房地产。这是一个领域。相反,使用字段的反射方法。

public class Foo { 

    public String d1; 
    public String d2 { get; set; } 

    public object getValue(String propertyName){ 
     var member = this.GetType().GetMember(propertyName).Single(); 
     if (member is PropertyInfo) 
     { 
      return ((PropertyInfo)member).GetValue(this, null); 
     } 
     else if (member is FieldInfo) 
     { 
      return ((FieldInfo)member).GetValue(this); 
     } 
     else throw new ArgumentOutOfRangeException(); 
    } 
} 
+0

您使用的'GetMember'的[overload](http://msdn.microsoft.com/zh-cn/library/xdtchs6z.aspx)不会返回集合,所以'Single'不是必需的。 – vcsjones

+0

@vcsjones:其实它返回一个数组(看你提供的链接),所以它是必要的。可能有多个成员(特别是方法)具有相同的名称。因此,虽然它违反了命名约定,但GetMember仍然需要返回一个集合。 – StriplingWarrior

+1

Gha。我甚至与我自己的死亡联系在一起。阅读失败。我错误地认为它相当于'GetProperty'(它不返回一个数组)和'GetProperties'(它确实)。 – vcsjones

4

d1不是房地产。这是一个领域。您将使用this.GetType().GetField通过反射来检索它。

public object getFieldValue(String fieldName){ 
    return this.GetType().GetField(fieldName).GetValue(this); 
} 

什么你可能想的是使的getValue返回属性字段的值。你可以使用GetMember可以告诉你它是一个属性还是一个字段。例如:

public object getValue(String memberName) { 
    var member = this.GetType().GetMember(memberName).Single(); 
    if (member.MemberType == MemberTypes.Property) { 
     return ((PropertyInfo)member).GetValue(this, null); 
    } 
    if (member.MemberType == MemberTypes.Field) { 
     return ((FieldInfo)member).GetValue(this); 
    } 
    else 
    { 
     throw new Exception("Bad member type."); 
    } 
}