C# 我可以从Func获取特定元数据吗<;T、 对象>;?
考虑以下代码:C# 我可以从Func获取特定元数据吗<;T、 对象>;?,c#,.net,linq,generics,reflection,C#,.net,Linq,Generics,Reflection,考虑以下代码: string propertyName; var dateList = new List<DateTime>() { DateTime.Now }; propertyName = dateList.GetPropertyName(dateTimeObject => dateTimeObject.Hour); // I want the propertyName variable to now contain the string "Hour" 字符串属性名称
string propertyName;
var dateList = new List<DateTime>() { DateTime.Now };
propertyName = dateList.GetPropertyName(dateTimeObject => dateTimeObject.Hour);
// I want the propertyName variable to now contain the string "Hour"
字符串属性名称;
var dateList=new List(){DateTime.Now};
propertyName=dateList.GetPropertyName(dateTimeObject=>dateTimeObject.Hour);
//我希望propertyName变量现在包含字符串“Hour”
以下是扩展方法:
public static string GetPropertyName<T>(this IList<T> list, Func<T, object> func) {
//TODO: would like to dynamically determine which
// property is being used in the func function/lambda
}
公共静态字符串GetPropertyName(此IList列表,Func Func){
//TODO:要动态确定
//属性正在func函数/lambda中使用
}
有办法做到这一点吗?我想,也许使用Expression
而不是Func
的另一种方法会给我更多的力量来找到我需要的东西,但我不知道如何找到
public static string GetPropertyName<T>(this IList<T> list, Expression<Func<T, object>> expr) {
// interrogate expr to get what I want, if possible
}
公共静态字符串GetPropertyName(此IList列表,表达式expr){
//如果可能的话,询问expr以得到我想要的
}
这是我第一次对Linq做这么深的事情,所以我可能遗漏了一些明显的东西。基本上,我喜欢传入lambdas的想法,这样我就可以进行编译时检查,但我不知道我关于如何在这种特殊情况下使用它们的想法是否有效
谢谢像这样的东西应该可以做到:
public static string GetPropertyName<T>(this IList<T> list, Expression<Func<T, object>> expr) {
MemberExpression member_expression = expr.Body as MemberExpression;
if (member_expression == null)
throw new ArgumentNullException("member_expression");
MemberInfo member = member_expression.Member;
PropertyInfo property = member as PropertyInfo;
string proname = memeber.name;
}
公共静态字符串GetPropertyName(此IList列表,表达式expr){
MemberExpression member_expression=将主体表示为MemberExpression;
if(成员_表达式==null)
抛出新的ArgumentNullException(“成员表达式”);
MemberInfo member=member\u expression.member;
PropertyInfo property=作为PropertyInfo的成员;
字符串proname=memeber.name;
}
警告:航空代码 这是我使用的版本,它返回一个
PropertyInfo
,但是获取名称并不重要
public static PropertyInfo GetProperty<T>(Expression<Func<T, object>> expression)
{
MemberExpression memberExpression = null;
if (expression.Body.NodeType == ExpressionType.Convert)
{
memberExpression = ((UnaryExpression) expression.Body).Operand as MemberExpression;
}
else if (expression.Body.NodeType == ExpressionType.MemberAccess)
{
memberExpression = expression.Body as MemberExpression;
}
if (memberExpression == null)
{
throw new ArgumentException("Not a member access", "expression");
}
return memberExpression.Member as PropertyInfo;
}
publicstaticpropertyinfo GetProperty(Expression)
{
MemberExpression MemberExpression=null;
if(expression.Body.NodeType==ExpressionType.Convert)
{
memberExpression=((UnaryExpression)expression.Body).操作数作为memberExpression;
}
else if(expression.Body.NodeType==ExpressionType.MemberAccess)
{
memberExpression=expression.Body作为memberExpression;
}
if(memberExpression==null)
{
抛出新ArgumentException(“非成员访问”、“表达式”);
}
返回memberExpression.Member作为PropertyInfo;
}
在这个博客上有一个非常简单快捷的方法:
因此:
Func Func=Name=>
“价值”
您可以获得lambda参数
函数委托的“名称”
电话:
func.Method.GetParameters()[0]。名称
(将返回“Name”)
下面是来自
安德烈:
公共字典哈希(params Func[]args)
T:在哪里上课
{
var items=newdictionary();
foreach(参数中的var func)
{
var item=func(空);
添加(func.Method.GetParameters()[0]。名称,项);
}
退货项目;
}
希望有帮助,
Patrick只是一个旁注:func.Method.GetParameters()[0]。与编译lambda并提取成员表达式、成员信息和名称相比,Name速度非常快 谢谢你回答内森,我很感激。你离得够近了,既然你说“像这样的事情应该会成功”,你从技术上讲并没有错!我将接受@gcores的回答,因为他的回答是正确的,我无需进行更改。不过我还是给了你+1分!Nathan和gcores在一些边缘情况下的回答有一点不同,比如可空小数(如果我没记错的话!)。对于这些属性,表达式的主体不是MemberExpression,而是一个UnaryExpression(在gcores的答案中处理)。@Jason太酷了,我会接受他的答案,因为它比我的答案更完整。@sighohwell:我知道,这就是为什么我接受了@gcores的答案,并且觉得@Nathan的答案足够好,值得一些赞扬,如果@gcores没有发布的话,它会帮我指明正确的方向。太棒了,这太完美了。现在我的破解完成了!:P啊,我讨厌不得不想出这些变通办法来让东西“像它应该的那样”工作。我的意思是,这很有趣,但当有真正的工作要做时,这太痛苦了。非常感谢。可能重复的
public Dictionary<string, T> Hash<T>(params Func<string, T>[] args)
where T : class
{
var items = new Dictionary<string, T>();
foreach (var func in args)
{
var item = func(null);
items.Add(func.Method.GetParameters()[0].Name, item);
}
return items;
}