When playing around with reflection in the new .NET Framework 4.5, I encountered a strange behavior that I found quite unexpected. The namespace System.Reflection provides some new extension methods for exploiting Type objects. Two of those are GetRuntimeProperty(string name) and GetRuntimeProperties().
Now imagine that you have a simple object with an internal property.
public class ObjectBase
{
protected int Id { get; set; }
public string Name { get; set; }
}
And you now try to exploit this type.
var properties = typeof(ObjectBase).GetRuntimeProperties();
// properties.Count = 2
var idProperty = typeof(ObjectBase).GetRuntimeProperty("Id");
var nameProperty = typeof(ObjectBase).GetRuntimeProperty("Name");
// idProperty = null
// nameProperty = System.String Name
As expected the properties
object holds two property definition for the Id and Name property defintions and the nameProperty holds the Name property definition. What was not expected was the idProperty
object to be null...
Coming from the .NET Framework, I guess this was intended by Microsoft architects but I must say it does not seem like something you would really expect to happen. I do believe such similar methods should behave the same but it seems that GetRuntimeProperty filters on public properties where GetRuntimeProperties apply no filters.
Does anybody have a reasonable explanation on why do Microsoft decided that those similar methods should have different behaviors? A design error?
Thanks.
Internally GetRuntimeProperty
calls Type.GetProperty(name)
which searches for the public property with the specified name. Property Id
is protected, thus it cannot be found.
public static PropertyInfo GetRuntimeProperty(this Type type, string name)
{
CheckAndThrow(type);
return type.GetProperty(name);
}
On the other hand GetRuntimeProperties
returns both public and non-public properties
public static IEnumerable<PropertyInfo> GetRuntimeProperties(this Type type)
{
CheckAndThrow(type);
return type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Static | BindingFlags.Instance);
}
Explanation: GetRuntimeProperties
purpose is returning IEnumerable<PropertyInfo>
collection of all properties, leaving you with filtering that collection via LINQ. You can select public, non-public or any other type of properties. With single property returned by GetRuntimeProperty
you don't need that flexibility, thus it is restricted for most common usage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With