ChatGPT解决这个技术问题 Extra ChatGPT

How to get the list of properties of a class?

How do I get a list of all the properties of a class?

This might be also helpful.

R
Robert Harvey

Reflection; for an instance:

obj.GetType().GetProperties();

for a type:

typeof(Foo).GetProperties();

for example:

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));
}

Following feedback...

To get the value of static properties, pass null as the first argument to GetValue

To look at non-public properties, use (for example) GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) (which returns all public/private instance properties ).


For completeness, there is also the ComponentModel, exposed by TypeDescriptor.GetProperties(...) - which allows dynamic runtime properties (reflection is fixed at compile-time).
Suggestion: Expand answer to cover protected/private/static/inherited properties.
The foreach statement you display even works from within the class you want to get the properties of :)
@Tadej what framework are you targeting? if you're using .NET core you need to ensure you have the using System.Reflection directive and the System.Reflection.TypeExtensions package referenced - this provides the missing API surface via extension methods
@HarryPehkonen, I think your example is not a property; it's a field, so you can extract all the info with foo.GetType().GetFields()
J
JHobern

You can use Reflection to do this: (from my library - this gets the names and values)

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;
}

This thing will not work for properties with an index - for that (it's getting unwieldy):

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[]{});
}

Also, to get only public properties: (see MSDN on BindingFlags enum)

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

This works on anonymous types, too! To just get the names:

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();
}

And it's just about the same for just the values, or you can use:

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

But that's a bit slower, I would imagine.


... but atype.GetProperty(prp.Name) is going to return prp?
Regarding the public properties bit, according to the linked MSDN article: "Note You must specify Instance or Static along with Public or NonPublic or no members will be returned.". So the sample code should be: t.GetProperties(BindingFlags.Instance | BindingFlags.Public) or t.GetProperties(BindingFlags.Static | BindingFlags.Public)
wasn't looking for the code, I was looking for an explanation to reflection and wow, so muchly appreciated! Make this generic and you might as well just say your program has super powers ;)
P
Pang
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;
}

This function is for getting list of Class Properties.


You might want to change this to use yield return. It isn't a big deal, but it's a better way of doing it.
I like this because it is (almost) the only answer that does not include the word reflection.
But this still uses reflection nevertheless.
i suppose this is much better pObject.GetType().GetProperties().Select(p=>p.Name)
J
Jacksonkr

Based on @MarcGravell's answer, here's a version that works in Unity C#.

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

J
Jon Limjap

You could use the System.Reflection namespace with the Type.GetProperties() mehod:

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

i
iknow

Try this:

var model = new MyObject();
foreach (var property in model.GetType().GetProperties())
{
    var descricao = property;
    var type = property.PropertyType.Name;
}

This answers the question the OP asked in the most direct way. 6 lines and done.
P
Pang

That's my solution

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;
        }
    }
}

Please. Please never do this. This S.O. should do its best to answer a question for the way something SHOULD be done. If your library requires, or even allows, your strongly-typed objects to be altered using string representations of their member names, there is a huge issue with your code base. Not to say this wasn't necessary for some scenario where you might obviously have no control over some other part of the system, company politics, or other things. But this looks like an Architectural Decision, and a horrible one. This is one decision in a chain of horrible programming choices.
C
Ch Usman

the following code will provide you the list of class properties/attributes/tablecolumns

var Properties = typeof(className).GetProperties().Select(x=>x.Name).Tolist();

D
Daan

You can use reflection.

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

K
Kjartan

Here is improved @lucasjones answer. I included improvements mentioned in comment section after his answer. I hope someone will find this useful.

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();
 }

I guess you can edit his answer for that, not make your own. Basically it would be one less answer to see which gives the same perspective.
S
Singaravelan

I am also facing this kind of requirement.

From this discussion I got another Idea,

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

This is also showing the property name.

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

this showing number of properties.

Thanks to all. This is nice discussion.