OK, this next is largely "for jollies", but heck, it does what we are
talking about [type-safe access giving name or MemberInfo]; uses C# 3
and .NET 3.5 though...
Of course, it won't work in attributes, so it doesn't help the OP
any...
Marc
using System;
using System.Reflection;
using System.Linq.Expressions;
static class Program
{
static void Main()
{
string test1 = MemberUtil.MemberName<Foo, string>(x => x.Bar);
string test2 = MemberUtil.MemberName<Foo, int>(x =>
x.Bloop());
string test3 = MemberUtil.MemberName<Foo>(x => x.Blap());
string test4 = MemberUtil.MemberName<Foo>(x => x.Blip(5)); //
can ignore ret...
}
}
class Foo
{
// "throws" to illustrate never invoked
public string Bar
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public int Bloop() { throw new NotImplementedException(); }
public decimal Blip(int someArg) { throw new
NotImplementedException(); }
public void Blap() { throw new NotImplementedException(); }
}
static class MemberUtil
{
public static string MemberName<TType,
TResult>(Expression<Func<TType, TResult>> member)
{
return MemberInfo(member).Name;
}
public static MemberInfo MemberInfo<TType,
TResult>(Expression<Func<TType, TResult>> member)
{
return ParseMemberInfo(member);
}
public static string MemberName<TType>(Expression<Action<TType>>
member)
{
return MemberInfo(member).Name;
}
public static MemberInfo
MemberInfo<TType>(Expression<Action<TType>> member)
{
return ParseMemberInfo(member);
}
static MemberInfo ParseMemberInfo(Expression expression)
{
while (expression.NodeType == ExpressionType.Lambda)
{
expression = ((LambdaExpression)expression).Body;
}
switch (expression.NodeType)
{
case ExpressionType.MemberAccess:
return ((MemberExpression)expression).Member;
case ExpressionType.Call:
return ((MethodCallExpression)expression).Method;
default:
throw new NotSupportedException("Unable to parse " +
expression.NodeType.ToString());
}
}
}