我可以从Func <t,object =“”>?</t,>中获取特定元数据

时间:2009-02-24 00:15:20

标签: 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"

这是扩展方法:

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
}

有办法做到这一点吗?我想也许这个其他方法,使用Expression<Func<T, object>>代替Func<T, object>会让我有更多的力量来找到我需要的东西,但我对此感到茫然。

public static string GetPropertyName<T>(this IList<T> list, Expression<Func<T, object>> expr) {
   // interrogate expr to get what I want, if possible
}

这是我第一次与Linq做了很多深入的事情,所以也许我错过了一些明显的东西。基本上我喜欢传入lambdas的想法,所以我得到了编译时检查,但是我不知道我在这种特殊情况下如何使用它们的想法是可行的。

由于

4 个答案:

答案 0 :(得分:12)

这是我使用的版本,它返回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;
}

答案 1 :(得分:6)

这是一个非常简单快捷的方法:http://blog.bittercoder.com/PermaLink,guid,206e64d1-29ae-4362-874b-83f5b103727f.aspx

  

所以给出:

     

Func func = Name =&gt;   “值”;

     

您可以获取lambda参数   来自函数委托的“名称”   主叫:

     

func.Method.GetParameters()[0],请将.Name   (将返回“姓名”)

     

这是修改后的Hash方法   安德烈:

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;
}

希望它有所帮助, 帕特里克

答案 2 :(得分:3)

这样的事情可以解决问题:

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;
}

警告:航空代码!

答案 3 :(得分:2)

只是旁注: func.Method.GetParameters()[0] .Name 与编译lambda并提取成员表达式,然后是成员信息,然后是名称相比,速度极快。