1

我想将一个强类型属性传递给一个方法,并将这个属性名用作 mhy 集合的字符串,所以我找到了一些代码,我可以在其中传递我的强类型属性:

public static void Add<TObject, TProperty>(this NameValueCollection collection, Expression<Func<TObject, TProperty>> expression, string value)
{
    var member = expression.Body as MemberExpression;

    collection.Add(member.Member.Name, value);
}

这可以工作并且可以满足我的要求,但我想知道这到底是如何工作的。我感兴趣的部分是方法 ( Add<Tobject, TProperty>) 的通用参数与Func表达式的结合。有人可以向我解释这是如何工作的吗?为什么我可以像这样调用这个方法collection.Add((MyObject m) => m.FullName, "Martijn")?为什么不需要使用它Add<MyObject, ???>(m => m.FullName, "Martijn")

更新:我现在将我的方法重构为:

public static void Add<TObject>(this NameValueCollection collection, Expression<Func<TObject, string>> expression, string value)
{
    var member = expression.Body as MemberExpression;

    collection.Add(member.Member.Name, value);
}
4

1 回答 1

1

Expression<T>是具有 delegate-type 签名的表达式树T。表达式树很复杂,但基本上:它不是作为操作的委托,而是描述操作的对象模型,并且可以检查它以查看它是如何组成的。

因此,anExpression<Func<TObject,TProperty>>是一个表达式树,表示接受TObject参数并返回TProperty结果的东西。

至于为什么不需要<MyObject, ???>手动告诉它:那是泛型类型推断,是正常的。给定一个通用方法,说:

void Foo<T>(T bar);

可以将其称为:

Foo<string>("abc");

但您也可以使用:

Foo("abc");

然后编译器将检查参数以查看它是否可以解析所有泛型类型参数 - 在这种情况下,"abc"is astring和 pin Tto be a string。如果它可以解决所有这些问题,则无需指定它们。

在您的示例中, theTObject被固定,因为您的 lambda 显式采用 a MyObject, via (MyObject) m,并且 theTProperty被固定到(大概) a string,因为m.FullName(大概)返回 a string。由于所有泛型类型参数都已自动解析,因此您无需<...>手动指定。

请注意,泛型类型推断仅适用于泛型方法(通过参数),不适用于泛型类型

于 2012-08-23T06:32:38.633 回答