A classes Type
metadata can be obtained in several ways. Two of them are:
var typeInfo = Type.GetType("MyClass")
and
var typeInfo = typeof(MyClass)
The advantage of the second way is that typos will be caught by the compiler, and the IDE can understand what I'm talking about (allowing features like refactoring to work without silently breaking the code)
Does there exist an equivalent way of strongly referencing members/properties/methods for metadata and reflection? Can I replace:
var propertyInfo = typeof(MyClass).GetProperty("MyProperty")
with something like:
var propertyInfo = property(MyClass.MyProperty)
No, unfortunately not. It's been discussed and even named: infoof
(pronounced "in-foof" for comedy value) but it's not been implemented... yet. Eric Lippert has a blog post about it.
The closest you can come in C# 3 is to make the compiler generate an expression tree, and then pull it out of that - but that's hardly pleasant.
I've just implemented an equivalent of constructions 'propertyof' 'methodof' 'fieldof' using Syste.Linq.Expressions
so instead of writing
var mi = typeof (string).GetMethod("Concat", new[] {typeof (object), typeof (object)});
you can use:
var mi = ReflectionHelper.MethodOf(() => string.Concat(new object(), new object()));
Why do we need this? because now we safe to refactor method, we use via reflection
listing of helper class (you may need to add some informative exceptions in methods):
/// <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
}
as I understand we could not use same aproach to getParameterInfo or EventInfo
Another approach to do that, described by Jb Evain, see: 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
In c# 6 there's still no infoof
but there is nameof
:
var propertyInfo = typeof(MyClass).GetProperty(nameof(MyClass.MyProperty))
It's certainly not more terse, but at least it's refactoring friendly.
No, there is no such syntax in c#.