Reputation: 7997
This is a follow-up to How to invoke static method in C#4.0 with dynamic type?
Is there a way to remove duplication when working with double.MaxValue, int.MaxValue, etc. by using dynamic keyword and/or generics?
Contrived example:
T? Transform<T>(Func<T?> continuation)
where T : struct
{
return typeof(T).StaticMembers().MaxValue;
}
Upvotes: 0
Views: 398
Reputation: 7997
With a little style and flair, same code:
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
PropertyInfo prop = _type.GetProperty(binder.Name,
BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public);
if (prop != null)
{
result = prop.GetValue(null, null);
return true;
}
FieldInfo field = _type.GetField(binder.Name,
BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public);
if (field != null)
{
result = field.GetValue(null);
return true;
}
result = null;
return false;
}
And a cache class, to avoid creating unneeded objects:
public static class StaticMembersDynamicWrapperExtensions
{
static Dictionary<Type, DynamicObject> cache =
new Dictionary<Type, DynamicObject>
{
{typeof(double), new StaticMembersDynamicWrapper(typeof(double))},
{typeof(float), new StaticMembersDynamicWrapper(typeof(float))},
{typeof(uint), new StaticMembersDynamicWrapper(typeof(uint))},
{typeof(int), new StaticMembersDynamicWrapper(typeof(int))},
{typeof(sbyte), new StaticMembersDynamicWrapper(typeof(sbyte))}
};
/// <summary>
/// Allows access to static fields, properties, and methods, resolved at run-time.
/// </summary>
public static dynamic StaticMembers(this Type type)
{
DynamicObject retVal;
if (!cache.TryGetValue(type, out retVal))
return new StaticMembersDynamicWrapper(type);
return retVal;
}
}
Upvotes: 0
Reputation: 60065
Modify class StaticMembersDynamicWrapper
in this way:
public override bool TryGetMember(GetMemberBinder binder, out object result) {
PropertyInfo prop = _type.GetProperty(binder.Name, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public);
if (prop == null) {
FieldInfo field = _type.GetField(binder.Name, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public);
if (field == null)
{
result = null;
return false;
}
else
{
result = field.GetValue(null, null);
return true;
}
}
result = prop.GetValue(null, null);
return true;
}
Problem of your code is that it only retrieves properties, but constants are actually fields.
Upvotes: 1