c# - 仅在使用 LINQ 时引用需要错误

标签 c# linq visual-studio-2013 extension-methods

我有 3 个 C# 项目/程序集,A、B 和 C。B 引用 A,C 引用 B。

在 A 中:

using System.Collections.Generic;

namespace A
{
    public class Dict : Dictionary<string, object> {}
    public class Options: Dict {}
}

在 B 中:

using System.Collections.Generic;
using A;

namespace B
{
    public class Client
    {
        public void M(IDictionary<string, string> d)
        {
            var dict = d.ToDict<Options>();
        }
    }

    public static class Extensions
    {
        public static T ToDict<T>(this IDictionary<string, string> dictionary)
           where T : Dict, new()
        {
            return new T();
        }
    }
}

在 C 中:

using System.Collections.Generic;
using B;

namespace C
{
    public class Worker
    {
        public void M()
        {
            var client = new Client();
            var d = new Dictionary<string, string> { { "k", "v" } };
            var strings = new [] { "one", "two" }; // never used
            client.M(d);
        }
    }
}

这一切都可以编译。

如果我在项目 C 中导入 System.Linq 命名空间并在调用 client.M(),出现编译错误:

The type 'A.Dict' is defined in an assembly that is not referenced. You must add a reference to assembly 'A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Extensions 类设置为 internal 或将其移动到不同的命名空间可以防止错误。

因为 B 应该包装 A 并向 C 隐藏其详细信息,所以让扩展方法公开是错误的。但我不明白为什么只有在引入 LINQ 时编译器才会选择它。

是否存在至少一种扩展方法会导致编译器的行为略有不同?

最佳答案

添加任何未解析的方法都会触发此错误。

我不记得是在哪里读到的,但是 C# (VS2013) 编译器在找到匹配的非扩展方法时将停止解析扩展方法。您可以通过在项目 C 中添加以下代码来验证这一点。

public static class Extensions
{
    public static void M(this Client c, IDictionary<string, string> d)
    {
        return;
    }
}

它不会导致任何错误!

当一个方法没有用非扩展方法解析时(例如,添加 "abc".Foo() 导致编译器错误),现在 C# 编译器开始扫描扩展方法。当它扫描 B.Extensions.ToDict 时,它不知道 Dict 是什么。但是,程序集 B 的元数据告诉编译器它来自 A.Dict,然后您会看到错误。

关于c# - 仅在使用 LINQ 时引用需要错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33167569/

相关文章:

c# - 从命令行生成 EF 存储过程方法

c# - 如何从 ASP.Net 核心中的 Json 文件播种 NetTopologySuite.Geometries.Point 数据

c# - 空间域卷积代码的性能

c# - 在 LINQ 中将 2 个 xml 合并为一个新 XML 的有效方法

c# - 使用 Linq 与自定义 IEqualityComparer 相交

javascript - 如何在javascript中反转字符串?

C#。执行 if( a == (b or c or d))。可能吗?

c# - 如何保护图书馆的用户免受错误的初始化?

sql - 如何实现自定义评级系统(日期相关性下降)

git - Visual Studio git-push 到两个存储库