扩展方法未编译

本文关键字:编译 方法 扩展 | 更新日期: 2023-09-27 18:14:56

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

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

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

扩展方法未编译

因为dynamic不使用扩展方法,即使c#编译器知道这是dynamic的操作,可以将整个操作推迟到运行时,它也知道这里没有Where方法可以工作。

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

"来。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; 
}

特别要注意编译器的消息:

'string'没有适用的名为'Extension'的方法,但似乎有一个名为'Extension'的扩展方法。不能动态分派扩展方法。考虑强制转换动态参数或调用扩展方法而不使用扩展方法语法。