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.
精彩评论