如何获取类的属性列表?


Answers:


797

反射; 对于一个实例:

obj.GetType().GetProperties();

对于类型:

typeof(Foo).GetProperties();

例如:

class Foo {
    public int A {get;set;}
    public string B {get;set;}
}
...
Foo foo = new Foo {A = 1, B = "abc"};
foreach(var prop in foo.GetType().GetProperties()) {
    Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(foo, null));
}

正在反馈...

  • 要获取静态属性的值,请null作为第一个参数传递给GetValue
  • 要查看非公共属性,请使用(例如)GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)(它将返回所有公共/私有实例属性)。

13
为了完整起见,还有由TypeDescriptor.GetProperties(...)公开的ComponentModel-允许动态运行时属性(反射在编译时固定)。
Marc Gravell

5
建议:扩大答案以涵盖受保护/私有/静态/继承的属性。
理查德

1
您显示的foreach语句甚至可以在要获取以下属性的类中使用:)
halfpastfour.am 2012年

从其他注释的陈述方式来看,我不清楚,但是使用所有3个标记也可以获取internal属性。也许我是唯一一个挂在private/ non-public语法上的人?
brichins 2013年

1
@Tadej您的目标框架是什么?如果您使用的是.NET Core,则需要确保已引用了using System.Reflection指令和System.Reflection.TypeExtensions程序包-这通过扩展方法提供了缺少的API表面
Marc Gravell

91

您可以使用Reflection来执行此操作:(从我的库中-这将获取名称和值)

public static Dictionary<string, object> DictionaryFromType(object atype)
{
    if (atype == null) return new Dictionary<string, object>();
    Type t = atype.GetType();
    PropertyInfo[] props = t.GetProperties();
    Dictionary<string, object> dict = new Dictionary<string, object>();
    foreach (PropertyInfo prp in props)
    {
        object value = prp.GetValue(atype, new object[]{});
        dict.Add(prp.Name, value);
    }
    return dict;
}

这对于具有索引的属性不起作用-为此(变得笨拙):

public static Dictionary<string, object> DictionaryFromType(object atype, 
     Dictionary<string, object[]> indexers)
{
    /* replace GetValue() call above with: */
    object value = prp.GetValue(atype, ((indexers.ContainsKey(prp.Name)?indexers[prp.Name]:new string[]{});
}

另外,仅获取公共属性:(请参见BindingFlags枚举上的MSDN

/* replace */
PropertyInfo[] props = t.GetProperties();
/* with */
PropertyInfo[] props = t.GetProperties(BindingFlags.Public)

这也适用于匿名类型!
仅获取名称:

public static string[] PropertiesFromType(object atype)
{
    if (atype == null) return new string[] {};
    Type t = atype.GetType();
    PropertyInfo[] props = t.GetProperties();
    List<string> propNames = new List<string>();
    foreach (PropertyInfo prp in props)
    {
        propNames.Add(prp.Name);
    }
    return propNames.ToArray();
}

对于值,它几乎是相同的,或者您可以使用:

GetDictionaryFromType().Keys
// or
GetDictionaryFromType().Values

但我想那会慢一些。


...但是atype.GetProperty(prp.Name)将返回prp吗?
Marc Gravell

5
关于公共属性位,根据链接的MSDN文章:“注意,您必须指定Instance或Static以及Public或NonPublic,否则将不返回任何成员。” 因此,示例代码应为:t.GetProperties(BindingFlags.Instance | BindingFlags.Public)t.GetProperties(BindingFlags.Static | BindingFlags.Public)
卡尔·沙曼

我不是在寻找代码,我在寻找反射和哇的解释,非常感谢!使其具有通用性,您不妨说您的程序具有超能力;)
Jaquarh 2016年

37
public List<string> GetPropertiesNameOfClass(object pObject)
{
    List<string> propertyList = new List<string>();
    if (pObject != null)
    {
        foreach (var prop in pObject.GetType().GetProperties())
        {
            propertyList.Add(prop.Name);
        }
    }
    return propertyList;
}

此函数用于获取类属性的列表。


7
您可能需要更改为使用yield return。这没什么大不了的,但这是一种更好的方法。
马修·豪根

1
我喜欢这样,因为它(几乎)是唯一不包含反射词的答案。

9
但这仍然使用反射。
GGG

2
我想这要好得多pObject.GetType()。GetProperties()。Select(p => p.Name)
令人失望的

23

您可以将System.Reflection命名空间与方法结合使用Type.GetProperties()

PropertyInfo[] propertyInfos;
propertyInfos = typeof(MyClass).GetProperties(BindingFlags.Public|BindingFlags.Static);

23

根据@MarcGravell的回答,这是在Unity C#中工作的版本。

ObjectsClass foo = this;
foreach(var prop in foo.GetType().GetProperties()) {
    Debug.Log("{0}={1}, " + prop.Name + ", " + prop.GetValue(foo, null));
}

8

那是我的解决方案

public class MyObject
{
    public string value1 { get; set; }
    public string value2 { get; set; }

    public PropertyInfo[] GetProperties()
    {
        try
        {
            return this.GetType().GetProperties();
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

    public PropertyInfo GetByParameterName(string ParameterName)
    {
        try
        {
            return this.GetType().GetProperties().FirstOrDefault(x => x.Name == ParameterName);
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

    public static MyObject SetValue(MyObject obj, string parameterName,object parameterValue)
    {
        try
        {
            obj.GetType().GetProperties().FirstOrDefault(x => x.Name == parameterName).SetValue(obj, parameterValue);
            return obj;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

6

您可以使用反射。

Type typeOfMyObject = myObject.GetType();
PropertyInfo[] properties =typeOfMyObject.GetProperties();

3

我也面临这种要求。

通过这次讨论,我得到了另一个想法,

Obj.GetType().GetProperties()[0].Name

这也显示了属性名称。

Obj.GetType().GetProperties().Count();

这显示了一些属性。

谢谢大家。这是很好的讨论。


3

这是改进的@lucasjones答案。他回答后,我在评论部分提到了改进之处。我希望有人会觉得有用。

public static string[] GetTypePropertyNames(object classObject,  BindingFlags bindingFlags)
{
    if (classObject == null)
    {
        throw new ArgumentNullException(nameof(classObject));
    }

        var type = classObject.GetType();
        var propertyInfos = type.GetProperties(bindingFlags);

        return propertyInfos.Select(propertyInfo => propertyInfo.Name).ToArray();
 }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.