C#中的另一个get属性名称(这个是静态的)

本文关键字:静态 另一个 get 属性 | 更新日期: 2023-09-27 17:59:32

我看了很多关于如何进行属性名称解析的例子,但我没有发现这能解决我的使用问题。

我对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版:感谢Darin,我更新了代码。我也需要让LastLoggedOn工作。

调试显示,expr的值是{x => Convert(x.LastLoggedOn)}(不知道Convert是什么意思)

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");
}

C#中的另一个get属性名称(这个是静态的)

只需从GetName静态方法中删除<T>,就可以开始了(顺便说一句,编译器应该已经警告过你了):

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);

您可以在Entity<T>:上调用您的静态方法

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

您已经使方法和类都是泛型的,都采用了一个类型参数。你可能只希望这个类是泛型的,因为它看起来就是你使用它的方式