Другое имя свойства get в C # (это статическое) - PullRequest
3 голосов
/ 20 июня 2011

Я посмотрел и везде много примеров, как сделать разрешение имени свойства, но я не нашел, что решило бы мое использование.

Моя идея 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");
}

Ответы [ 2 ]

5 голосов
/ 20 июня 2011

Просто удалите <T> из статического метода GetName, и все готово (кстати, компилятор должен был предупредить вас об этом):

public class Entity<T> where T : class
{
    public static string GetName(Expression<Func<T, object>> expr)
    {
        return ((MemberExpression)expr.Body).Member.Name;
    }
}

public class User: Entity<User>
{
    public String UserName { get; set; }
}

Теперь вы можете написать:

string name = User.GetName(x => x.UserName);
1 голос
/ 20 июня 2011

Вы можете вызвать свой статический метод для Entity<T>:

string name = Entity<User>.GetName<User>(u => u.UserName);

Вы сделали и метод, и класс родовым, оба приняв параметр типа.Вы, вероятно, хотите, чтобы класс был универсальным, потому что, похоже, именно так вы его используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...