【问题标题】:Is there a C# equivalent of typeof for properties/methods/members?属性/方法/成员是否有与 typeof 等效的 C#?
【发布时间】:2010-03-19 15:58:09
【问题描述】:

可以通过多种方式获取类Type 元数据。其中两个是:

var typeInfo = Type.GetType("MyClass")

var typeInfo = typeof(MyClass)

第二种方式的好处是错别字会被编译器捕捉到,IDE可以理解我在说什么(允许重构之类的功能在不默默破坏代码的情况下工作)

是否存在对元数据和反射强引用成员/属性/方法的等效方法?可以换吗:

var propertyInfo = typeof(MyClass).GetProperty("MyProperty")

类似:

var propertyInfo = property(MyClass.MyProperty)

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

    不,很遗憾没有。它已经被讨论过,甚至被命名为:infoof(发音为“in-foof”的喜剧价值)但它还没有被实施……但是。 Eric Lippert 有一个blog post about it

    在 C# 3 中最接近的方法是让编译器生成一个表达式树,然后将其拉出 - 但这并不令人愉快。

    【讨论】:

      【解决方案2】:

      我刚刚使用 Syste.Linq.Expressions 实现了等效的构造 'propertyof' 'methodof' 'fieldof'

      所以不要写

      var mi = typeof (string).GetMethod("Concat", new[] {typeof (object), typeof (object)});
      

      你可以使用:

      var mi = ReflectionHelper.MethodOf(() => string.Concat(new object(), new object()));
      

      为什么我们需要这个?因为现在我们可以安全地重构方法,我们通过反射使用

      帮助类列表(您可能需要在方法中添加一些信息异常):

      /// <summary>
      /// Represents a set of helpers for .net reflection
      ///  </summary>
      public static class ReflectionHelper
      {
          #region Public methods
      
          /// <summary>
          /// Gets a MethodInfo object from specified expression
          ///  </summary>
          /// <typeparam name="TResult"></typeparam>
          /// <param name="methodExpression"></param>
          /// <returns></returns>
          public static MethodInfo MethodOf<TResult>(Expression<Func<TResult>> methodExpression)
          {
              return ((MethodCallExpression)methodExpression.Body).Method;
          }
      
          /// <summary>
          /// Gets a MethodInfo object from specified expression
          ///  </summary>
          /// <param name="methodExpression"></param>
          /// <returns></returns>
          public static MethodInfo MethodOf(Expression<Action> methodExpression)
          {
              return ((MethodCallExpression)methodExpression.Body).Method;
          }
      
          /// <summary>
          /// Gets a MethodInfo object from specified expression
          ///  </summary>
          /// <param name="methodExpression"></param>
          /// <returns></returns>
          public static MethodInfo MethodOf<TInstance, TResult>(Expression<Func<TInstance, TResult>> methodExpression)
          {
              return ((MethodCallExpression)methodExpression.Body).Method;
          }
      
          /// <summary>
          /// Gets a MethodInfo object from specified expression
          ///  </summary>
          /// <param name="methodExpression"></param>
          /// <returns></returns>
          public static MethodInfo MethodOf<TInstance>(Expression<Action<TInstance>> methodExpression)
          {
              return ((MethodCallExpression)methodExpression.Body).Method;
          }
      
          /// <summary>
          /// Gets a PropertyInfo object from specified expression
          ///  </summary>
          /// <param name="propertyGetExpression"></param>
          /// <returns></returns>
          public static PropertyInfo PropertyOf<TProperty>(Expression<Func<TProperty>> propertyGetExpression)
          {
              return ((MemberExpression)propertyGetExpression.Body).Member as PropertyInfo;
          }
      
          /// <summary>
          /// Gets a PropertyInfo object from specified expression
          ///  </summary>
          /// <param name="propertyGetExpression"></param>
          /// <returns></returns>
          public static PropertyInfo PropertyOf<TInstance, TProperty>(Expression<Func<TInstance, TProperty>> propertyGetExpression)
          {
              return ((MemberExpression)propertyGetExpression.Body).Member as PropertyInfo;
          }
      
          /// <summary>
          /// Gets a FieldInfo object from specified expression
          ///  </summary>
          /// <param name="fieldAccessExpression"></param>
          /// <returns></returns>
          public static FieldInfo FieldsOf<TProperty>(Expression<Func<TProperty>> fieldAccessExpression)
          {
              return ((MemberExpression)fieldAccessExpression.Body).Member as FieldInfo;
          }
      
          //TODO: ConstructorOf(...)
      
          #endregion //Public methods
      }
      

      据我了解,我们不能使用相同的方法来获取参数信息或事件信息

      Jb Evain 描述的另一种方法,请参阅:http://evain.net/blog/articles/2010/05/05/parameterof-propertyof-methodof?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+jbevain+%28Jb+in+a+nutshell%29

      【讨论】:

      • +1 @Marvinsky 这是一个很酷的想法,如果你使用 default(type) 而不是 new type() 作为参数,这样你就不必实例化任何东西了?
      • 是的,它会起作用,虽然,即使你写 'new Something()' - 它也不会被实例化,因为它只是一个表达式,强制我们的表达式更好尽可能短,所以 default(Something) - 更好
      • 不错的解决方案。但是,它很慢。
      【解决方案3】:

      在 c# 6 中仍然没有 infoof 但有 nameof

      var propertyInfo = typeof(MyClass).GetProperty(nameof(MyClass.MyProperty))
      

      当然不是更简洁,但至少它对重构友好。

      【讨论】:

        【解决方案4】:

        不,c#中没有这样的语法。

        【讨论】:

          猜你喜欢
          • 2017-02-16
          • 2021-12-04
          • 2013-06-03
          • 1970-01-01
          • 2019-03-07
          • 1970-01-01
          • 2014-05-28
          • 1970-01-01
          • 2016-06-17
          相关资源
          最近更新 更多