13

I am writing a Windows 8 application in C# and XAML. I have a class with many properties of the same type that are set in the constructor the same way. Instead of writing and assignment for each of the properties by hand I want to get a list of all the properties of certain type on my class and set them all in a foreach.

In "normal" .NET I would write this

var properties = this.GetType().GetProperties();
foreach (var property in properties)
{
    if (property.PropertyType == typeof(Tuple<string,string>))
    property.SetValue(this, j.GetTuple(property.Name));
}

where j is a parameter of my constructor. In WinRT the GetProperties() does not exist. Intellisense for this.GetType(). does not show anything useful I could use.

Igor Kulman
  • 16,211
  • 10
  • 57
  • 118

2 Answers2

16

You need to use GetRuntimeProperties instead of GetProperties:

var properties = this.GetType().GetRuntimeProperties();
// or, if you want only the properties declared in this class:
// var properties = this.GetType().GetTypeInfo().DeclaredProperties;
foreach (var property in properties)
{
    if (property.PropertyType == typeof(Tuple<string,string>))
    property.SetValue(this, j.GetTuple(property.Name));
}
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • 2
    Error: 'System.Type' does not contain a definition for 'GetTypeInfo' – Igor Kulman Nov 02 '12 at 15:01
  • 3
    It's an extension method, you need to import the `System.Reflection` namespace – Thomas Levesque Nov 02 '12 at 15:02
  • After importing `System.Reflection` I get 'System.Reflection.TypeInfo' does not contain a definition for 'GetProperties'. Any other imports needed? – Igor Kulman Nov 02 '12 at 15:05
  • 1
    @IgorKulman, sorry, forgot about that... you can use either `GetRuntimeProperties()` (to get all properties, including the inherited ones) or `DeclaredProperties` (to get only properties declared by this type). See my edit – Thomas Levesque Nov 02 '12 at 15:11
  • 3
    When reading the documentation (http://msdn.microsoft.com/en-us/library/windows/apps/system.reflection.typeinfo.aspx), you have to ignore those items that don't have a green briefcase icon (Supported in .NET for Windows Store apps). – Tergiver Nov 02 '12 at 15:12
  • TypeInfo.GetRuntimeProperties isn't available for Windows RT, either. See Rico's answer below, it works like a charm. – Nick Pruehs May 13 '14 at 14:18
  • @NickPruehs, [yes it is](http://msdn.microsoft.com/EN-US/library/hh875138.aspx). But it's an extension method, you need to import the System.Reflection namespace – Thomas Levesque May 13 '14 at 16:49
  • My edit to make the code above compilable was rejected by respectable peers, so I just post it here. The first line should look like `this.GetType().GetRuntimeProperties()` to satisfy the compiler (`GetRuntimeProperties()` is an extension method for `Type`, not `TypeInfo`). – Shaddix Dec 29 '14 at 06:38
  • @Shaddix, your edit was correct, but incomplete, since the text still mentioned `TypeInfo` ;). The situation with `Type`/`TypeInfo` is a bit confusing, because in the full .NET framework, `TypeInfo` inherits from `Type` (so the code in my post compiled fine on this platform), but in WinRT it doesn't, so it didn't compile... To add to the confusion, the documentation doesn't mention the fact that `TypeInfo` inherits from `Type` in .NET 4.5... no idea why. – Thomas Levesque Dec 29 '14 at 10:14
  • @Shaddix, more information [here](http://blogs.msdn.com/b/dotnet/archive/2012/08/28/evolving-the-reflection-api.aspx). See the section "Compatibility across .NET target frameworks" – Thomas Levesque Dec 29 '14 at 10:19
6

Try this:

public static IEnumerable<PropertyInfo> GetAllProperties(this TypeInfo type)
{
    var list = type.DeclaredProperties.ToList();

    var subtype = type.BaseType;
    if (subtype != null)
        list.AddRange(subtype.GetTypeInfo().GetAllProperties());

    return list.ToArray();
}

and use it like this:

var props = obj.GetType().GetTypeInfo().GetAllProperties();

Update: Use this extension method only if GetRuntimeProperties is not available because GetRuntimeProperties does the same but is a built-in method.

Rico Suter
  • 11,548
  • 6
  • 67
  • 93