使用动态关键字访问常量

时间:2011-04-21 20:22:57

标签: .net dynamic c#-4.0 generics

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

2 个答案:

答案 0 :(得分: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; 
}

您的代码问题在于它只检索属性,但常量实际上是字段。

答案 1 :(得分: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;
   }
}