繁体   English   中英

仅在使用LINQ时引用所需的错误

[英]Reference required error only when using LINQ

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

在一个:

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

这一切都编译好了。

如果我在Project C中导入System.Linq命名空间并添加行strings.Select(s => s); (或任何LINQ方法)在调用client.M() ,我得到一个编译器错误:

“A.Dict”类型在未引用的程序集中定义。 您必须添加对程序集“A,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null”的引用。

使Extensionsinternal或将其移动到不同的命名空间可以防止错误。

由于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 ,然后你看到错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM