尝试调用有效方法重载时出现奇怪的“程序集未引用”错误

我在Assembly A使用方法重载:

 public static int GetPersonId(EntityDataContext context, string name) { var id = from ... in context... where ... select ...; return id.First(); } public static int GetPersonId(SqlConnection connection, string name) { using (var context = new EntityDataContext(connection, false)) { return GetPersonId(context, name); } } 

当我尝试从Assembly B调用第二个重载时,VS会产生以下编译时错误:

“System.Data.Entity.DbContext”类型在未引用的程序集中定义。 您必须添加对程序集’EntityFramework,Version = 6.0.0.0,Culture = neutral,PublicKeyToken = …’的引用。

Assembly B参考Assembly A entity framework仅在Assembly A引用,因为Assembly B不使用它。 Assembly B的电话如下:

 using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); var id = AssemblyA.GetPersonId(connection, name); // compiler error ... } 

我不明白的是, 如果我将 Assembly A 的方法签名更改为例如:

 public static int GetPersonId(SqlConnection connection, string name, bool empty) 

并将通话更改为:

 var id = AssemblyA.GetPersonId(connection, name, true); // no error 

为什么我的代码在第一种情况下没有编译? 它似乎与entity framework无关,因为错误表明了这一点。 我一直认为C#允许方法重载,方法签名只在参数类型上有所不同。 例如,我可以按预期运行以下代码而不会出现问题:

 static void DoStuff(int a, int b) { ... } static void DoStuff(int a, float b) { ... } DoStuff(10, 5); DoStuff(10, 5.0f); 

那么,尽管有明显的合法超载,为什么我会在我的情况下得到错误?

请注意,从Assembly B调用其他内部使用EntityDataContext方法没有问题,唯一的区别是这些方法没有重载。


背景

EntityDataContextinheritanceEF的DbContext

 public partial class EntityDataContext : DbContext { public EntityDataContext() : base("name=EntityDataContext") { } public EntityDataContext(DbConnection connection, bool contextOwnsConnection) : base(connection, contextOwnsConnection) { } ... } 

我首先使用带有EF 6代码的.NET 4.0到现有数据库,并添加了一些自定义ctor重载。

C#标准规定通过比较每个匹配的签名来确定哪个更合适,从而执行重载决策(第7.5.3节)。 它没有说明缺少引用时会发生什么,所以我们必须推断它仍然需要比较那些未引用的类型。

在您的情况下,编译器需要对EntityDataContext的引用才能比较两个重载。 您的呼叫完全匹配签名,理论上您不应该这样,但标准没有指定任何此类短路行为。