问题描述
|
假设我有:
class Person
{
[ColumnAttribute(\"ID\"]
public int Id;
[ColumnAttribute(\"Name\"]
public string Name;
[ColumnAttribute(\"DateOfBirth\"]
public date BirthDate;
}
我想创建一个将被如下调用的方法
GetPropertyColumn<Person>(e=>e.Name)
此方法将返回由ColumnAttribute属性定义的字符串。
问题是我无法定义此方法。
我试过了
public string GetPropertyColumn<T,U>(Expression<Func<T,U>> Lamda)
但是问题是我只能指定T而不能指定U,所以它不起作用。
有什么帮助吗?
谢谢
编辑:
感谢您的回答,但我有很多答案,您需要实例化Person,但我不想这样做。
因为我只想知道给定列的类内部定义的属性。
解决方法
如果您有一个具有2个泛型类型(T和U)的泛型方法,则都将同时指定两个或最多两个。如果无法做到这一点,请考虑一个取值为taking3 expression的表达式(删除U),并在运行时检查该表达式树中的强制转换/转换节点。您也可以做一些事情来推断两种类型,但这可能需要更多的重构。
,[编辑3]
public static string GetPropertyColumn<T>(Expression<Func<T,object>> f)
{
Type t = typeof(T);
MemberExpression memberExpression = null;
if (f.Body.NodeType == ExpressionType.Convert)
{
memberExpression = ((UnaryExpression)f.Body).Operand as MemberExpression;
}
else if (f.Body.NodeType == ExpressionType.MemberAccess)
{
memberExpression = f.Body as MemberExpression;
}
string name = memberExpression.Member.Name;
System.Reflection.FieldInfo fi = t.GetField(name);
object[] attrs = fi.GetCustomAttributes(true);
foreach (var attr in attrs)
{
ColumnAttribute columnAttr = attr as ColumnAttribute;
if (columnAttr != null)
{
return columnAttr.Name;
}
}
return string.Empty;
}
使用:
Console.WriteLine(GetPropertyColumn<Person>(e => e.Name));
,使其成为扩展方法:
static class ExtensionMethods
{
public static string GetPropertyColumn<T,U>(this T obj,Expression<Func<T,U>> selector)
{
... // whatever
}
}
并按如下所示使用它:
Person person = ...
string propertyColumn = person.GetPropertyColumn(p => p.Name);
您不需要指定T,因为它是从第一个参数推断出来的,也不需要指定U,因为它是从lambda的返回类型推断出来的
请注意,您不需要将其定义为扩展方法,也可以是常规方法。然后,您将像这样使用它:
Person person = ...
string propertyColumn = GetPropertyColumn(person,p => p.Name);