Я посмотрел и везде много примеров, как сделать разрешение имени свойства, но я не нашел, что решило бы мое использование.
Моя идея User
выглядит следующим образом:
class Entity<T> where T : class
{
public static String GetName<T>(Expression<Func<T, object>> expr)
{
return ((MemberExpression)expr.Body).Member.Name;
}
}
class User : Entity<User>
{
public String UserName { get; set; }
public DateTime LastLoggedOn { get; set; }
}
Вопрос: Как реализовать разрешение имени свойства, если я хочу использовать его следующим образом?
Debug.Assert("UserName" == User.GetField(x => x.UserName));
Debug.Assert("LastLoggedOn" == User.GetField(x => x.LastLoggedOn));
Любая помощь будет оценена. Спасибо.
Примечания: я мог бы сделать var u = new User();
, а затем u.GetName(() => u.UserName)
, но в моем случае у меня нет экземпляра объекта
РЕДАКТИРОВАТЬ 1 : Благодаря Дарину, я обновил свой код. Мне нужно, чтобы LastLoggedOn
тоже работал.
Отладка показывает, что значение expr
равно {x => Convert(x.LastLoggedOn)}
(не знаю, что означает преобразование)
InvalidCastException was unhandled
Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'System.Linq.Expressions.MemberExpression'.
РЕДАКТИРОВАТЬ 2 / Ответ : После некоторой отладки я составил это «решение». Мне это не нравится, но, похоже, работает.
public static string GetName(Expression<Func<T, object>> expression)
{
MemberExpression memberExp = expression.Body as MemberExpression;
if (memberExp != null)
return memberExp.Member.Name;
// for DateTime
UnaryExpression unaryExp = expression.Body as UnaryExpression;
if (unaryExp != null)
{
memberExp = unaryExp.Operand as MemberExpression;
if (memberExp != null)
return memberExp.Member.Name;
}
throw new ArgumentException("'expression' should be a member expression or a method call expression.", "expression");
}