2011-04-21 73 views
0

访问常量这是一个后续How to invoke static method in C#4.0 with dynamic type?与动态关键字

有没有办法用double.MaxValue,int.MaxValue等工作时,通过使用动态关键字和/或仿制药,以消除重复?

人为的例子:

T? Transform<T>(Func<T?> continuation) 
    where T : struct 
    { 
    return typeof(T).StaticMembers().MaxValue; 
    } 
+1

什么样的重复? – Andrey 2011-04-21 20:24:51

+1

@ .net常量中的GregC不是编译时。 – Andrey 2011-04-21 20:25:22

+0

@Andrey:我用一个例子更新了我的Q – GregC 2011-04-21 20:27:30

回答

1

修改类StaticMembersDynamicWrapper这样:

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

你的代码的问题是,它仅检索属性,但常量实际上领域。

0

随着一点点的风格和才华,同样的代码:

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

和高速缓存类,以避免不必要的创建对象:

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