开发者

Another get property name in C# (this one is static)

I looked and everywhere are many examples how to do property name resolution, but I didn't find that would solve my usage.

My idea of User looks like this:

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

class User : Entit开发者_开发技巧y<User>
{
    public String UserName { get; set; }
    public DateTime LastLoggedOn { get; set; }
}

Question: How to implement property name resolution if I want to use it like this?

Debug.Assert("UserName" == User.GetField(x => x.UserName));
Debug.Assert("LastLoggedOn" == User.GetField(x => x.LastLoggedOn));

Any help would be appreciated. Thanks.

Notes: I could do var u = new User(); and then u.GetName(() => u.UserName) but in my case, I don't have an instance of the entity

EDIT 1: Thanks to Darin, I updated my code. I need to get LastLoggedOn work too.

Debugging shows, that value of expr is {x => Convert(x.LastLoggedOn)} (don't know what the Convert means)

InvalidCastException was unhandled
  Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'System.Linq.Expressions.MemberExpression'.

EDIT 2/Answer: After some debugging I've composed this "solution". I don't like it, but it seems to work.

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


Just remove the <T> from the GetName static method and you are good to go (the compiler should have warned you about this by the way):

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

Now you can write:

string name = User.GetName(x => x.UserName);


You can call your static method on Entity<T>:

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

You have made both the method and the class generic, both taking a type parameter. You probably only want the class to be generic, because it looks like that is how you are using it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜