1

考虑以下简单的扩展方法:

public static class MyExtensions
{
    public static int DemoLength(this string str, string toAdd)
    {
        return (str + toAdd).Length;
    }
}

我不得不称它为:

  1. 随着扩展

    int result1 = "hello".DemoLength("all");

  2. 从静态类

    int result2 = MyExtensions.DemoLength("hello", "all");

现在考虑另一个例子:

IQueryable<int> source = Enumerable.Range(0, 10).AsQueryable();
Expression<Func<int, bool>> expr = t => (t & 1) == 0; // Even numbers
LambdaExpression lambda = expr;
  1. 随着扩展

    IQueryable<int> result1 = source.Where((dynamic)lambda);

  2. 从静态类

    IQueryable<int> result2 = Queryable.Where(source, (dynamic)lambda);

为什么这次扩展方法不能编译

4

1 回答 1

3

因为dynamic不使用扩展方法,即使 C# 编译器知道这是一个dynamic操作并且可以将整个事情推迟到运行时,它也知道没有任何Where方法可以在这里工作。

编译器告诉我们所有这些(取自编译示例中的代码):

“System.Linq.IQueryable”没有名为“Where”的适用方法,但似乎具有该名称的扩展方法。扩展方法不能动态调度。考虑强制转换动态参数或在没有扩展方法语法的情况下调用扩展方法。

Queryable.Where版本有效,因为它不再使用扩展方法。

用一个简单的例子来说明:

static void Extension<T>(this string s, T t) {}
static void Main()
{
    string s = "";
    int i = 123;
    s.Extension(i); // fine
    s.Extension((dynamic)i); // doesn't compile; 
}

特别要注意编译器消息:

“字符串”没有名为“扩展”的适用方法,但似乎具有该名称的扩展方法。扩展方法不能动态调度。考虑强制转换动态参数或在没有扩展方法语法的情况下调用扩展方法。

于 2013-05-23T12:30:16.770 回答