.net定义采用lambda表达式的函数

时间:2010-12-10 09:03:26

标签: c# .net asp.net-mvc-2

我想定义一个类似MVC扩展模板函数TextBoxFor

的函数

该函数的有趣之处在于我不必指定TProperty类型。 如何在我的函数定义中设置它。

我的代码如下:

public class Helper<TItem>
{
    public string GetMemberName(Expression<Func<TItem, TProperty>> expression)
    {
        ... returns TProperty.Name

    }
}

实际问题是这不能编译...因为它无法找到TProperty类型。

我想要的结果是使用类型...定义类一次,然后使用函数GetMemberName获取每个成员的名称,如MVC框架中所示。

Helper<Employee> h = new Helper<Employee>();
string name = h.GetMemberName(e=>e.Name);
....

我不想在编写代码时强制指定TProperty类型。基本上它可以是任何对象。

谢谢,

拉​​杜

4 个答案:

答案 0 :(得分:3)

这就是你需要的:

public class Helper<TItem>
{
    public string GetMemberName<TProperty>(Expression<Func<TItem, TProperty>> expression)
    {
        return string.Empty; // I didn't implement it
    }
}

只需将<TProperty>附加到您的方法名称即可使其成为通用名称。 TProperty的类型可以从提供的表达式中推断出来,因此您在使用时无需指定其类型,可以简单地说:

Helper<Employee> h = new Helper<Employee>();
h.GetMemberName( e=>e.Name); //if Employee has such a property

答案 1 :(得分:1)

以下函数返回使用lambda表达式传递给它的任何属性的名称:

    public static string Property<T>(Expression<Func<T>> e)
    {
        var member = (MemberExpression)e.Body;
        return member.Member.Name;
    }

答案 2 :(得分:0)

您可以使用ModelMetaData类从Expression中提取信息。

public string GetMemberName<TProperty>(Expression<Func<TItem, TProperty>> expression) {
   var meta = ModelMetaData.FromLambdaExpression(expression, null);
   return meta.PropertyName; // Or something else
}

答案 3 :(得分:0)

我曾经写过这个函数,但我记不起来了。 但首先将委托签名更改为此Func<T, object>,然后对于简单数据类型,获取表达式主体并将其强制转换为 MemberExpression 并获取第一个参数的名称

如果被访问的成员是一个复杂的成员,你必须将表达式主体强制转换为 UnaryExpression ,取第一个参数并将其转换为 MemberExpression 并执行你先做的事情步骤

调试功能时使用QuickWatch可以引导您找到解决方案。 值得一提的是,在MVC代码中阅读HtmlHelper可能会有所帮助。

修改 大致记得

更好的方法是将此函数编写为扩展方法(如果需要,在适用的情况下对类型进行约束),以便不再需要提供Employee类型,因为它是从使用中推断出来的。

所以你的功能就是这样:

public static class Helper
{
    public static string Item<TItem,TMember>(this TItem obj, Expression<Func<TItem, TMember>> expression)
    {
        if (expression.Body is MemberExpression)
        {
            return ((MemberExpression)(expression.Body)).Member.Name;
        }
        if(expression.Body is UnaryExpression)
        {
            return ((MemberExpression)((UnaryExpression)(expression.Body)).Operand).Member.Name;
        }
        throw new InvalidOperationException();
    }
}

所以你的代码会更清晰

Employee emp = new Employee();
emp.Item(o=>o.Name);

希望能帮到你