我看了,到处都是很多如何进行属性名称解析的例子,但我没有发现这会解决我的使用问题。
我对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)}
(不知道转换的含义)
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");
}
答案 0 :(得分:5)
只需从<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 :(得分:1)
您可以在Entity<T>
上调用静态方法:
string name = Entity<User>.GetName<User>(u => u.UserName);
您已经使方法和类都是通用的,都采用了类型参数。您可能只希望该类是通用的,因为它看起来就是您使用它的方式。