假设我有:
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,所以它不起作用
任何帮助?
感谢
感谢您的答案,但我得到了很多答案,您需要即时通知人员,但我不想这样。
因为我只想知道给定在类中定义的属性的列。
答案 0 :(得分:2)
[编辑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));
答案 1 :(得分:2)
如果你有一个带有2种泛型类型(T和U)的泛型方法,那么两者都被指定,或者两者都被推断出来。如果无法做到这一点,请考虑使用Func<T,object>
(删除U)的表达式,并在运行时检查表达式树时从表达式树中删除强制转换/转换节点。您也可以做一些事情来推断这两种类型,但这可能需要更多的重构。
答案 2 :(得分:1)
将其作为扩展方法:
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);