How to get the list of properties of a class?
Asked Answered
T

11

781

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

Toe answered 10/4, 2009 at 9:29 Comment(1)
This might be also helpful.Borgia
K
1032

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 ).
Kroll answered 10/4, 2009 at 9:33 Comment(13)
For completeness, there is also the ComponentModel, exposed by TypeDescriptor.GetProperties(...) - which allows dynamic runtime properties (reflection is fixed at compile-time).Kroll
Suggestion: Expand answer to cover protected/private/static/inherited properties.Quar
The foreach statement you display even works from within the class you want to get the properties of :)Sports
It wasn't clear to me from the way the additional comments are stated, but using all 3 flags gets you internal properties as well. Maybe I'm the only one who got hung up on the private/non-public syntax?Emeliaemelin
What if that property "A" is another class that also contains properties? I think there should be some kind of a recursive method created. The search would continue until the type of a property is "System", like this: Type.GetType(innerProp.PropertyType.FullName).Namespace == "System".Unequal
When need only properties declared in the current class the BindingFlags.DeclaredOnly flag can be supplied, for example GetProperties(... | BindingFlags.DeclaredOnly)Psalmbook
I get an error saying that GetProperties() does not exist.Centaury
@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 methodsKroll
I can't "install" the System.Reflection.TypeExtensions nuget package. My project is using .NETPortable,Version=v4.5,Profile=Profile7. Is this even possible in a PCL xamarin application?Centaury
@Tadej there do appear to be some Xamarin builds of that, but I can't tell you about PCLs; PCLs are notoriously awkward. There should be a similar reflection API available - look for .Properties, for example.Kroll
BEWARE: If you don't create a getter, the property won't appear with this method. For example, if you just declare a property as public (I.e. public string someProperty;), and then simply assign values to it, reflection doesn't seem to be useful. "Fix" that by adding { get; } to the end. Can others confirm this, please?Sublunary
You would do well to wrap that in a Try/Catch block. For example, getting the Length property on a FileInfo object throws an System.Reflection.TargetInvocationException Exception unless the subject file exists.Gregoriogregorius
@HarryPehkonen, I think your example is not a property; it's a field, so you can extract all the info with foo.GetType().GetFields()Geographer
F
123

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.

Flout answered 10/4, 2009 at 9:34 Comment(3)
... but atype.GetProperty(prp.Name) is going to return prp?Kroll
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)Annular
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 ;)Athlete
C
44
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.

Comeon answered 24/7, 2014 at 2:57 Comment(4)
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.Sensory
I like this because it is (almost) the only answer that does not include the word reflection.Volition
But this still uses reflection nevertheless.Padrone
i suppose this is much better pObject.GetType().GetProperties().Select(p=>p.Name)Hersh
G
33

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));
}
Griseofulvin answered 14/7, 2017 at 16:22 Comment(0)
N
25

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

PropertyInfo[] propertyInfos;
propertyInfos = typeof(MyClass).GetProperties(BindingFlags.Public|BindingFlags.Static);
Nonce answered 10/4, 2009 at 9:35 Comment(0)
C
16

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

var Properties = typeof(className).GetProperties().Select(x=>x.Name).ToList();
Colonize answered 20/5, 2021 at 8:4 Comment(0)
A
15

Try this:

var model = new MyObject();
foreach (var property in model.GetType().GetProperties())
{
    var descricao = property;
    var type = property.PropertyType.Name;
}
Ancilin answered 26/8, 2020 at 9:34 Comment(1)
This answers the question the OP asked in the most direct way. 6 lines and done.Lillalillard
J
10

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;
        }
    }
}
Jetport answered 20/9, 2015 at 6:20 Comment(1)
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.Mock
J
7

You can use reflection.

Type typeOfMyObject = myObject.GetType();
PropertyInfo[] properties =typeOfMyObject.GetProperties();
Jacal answered 10/4, 2009 at 9:33 Comment(0)
E
3

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();
 }
Emetic answered 19/9, 2016 at 8:8 Comment(1)
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.Dudek
J
2

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.

Joselyn answered 4/6, 2014 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.