问题描述
我在 Assembly A
中使用方法重载:
I'm using method overloading in 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 会产生以下编译时错误:
When I try to call the second overload from Assembly B
, VS produces the following compile-time error:
类型System.Data.Entity.DbContext"在一个程序集中定义,该程序集没有被引用.您必须添加对程序集的引用'EntityFramework,版本=6.0.0.0,文化=中性,PublicKeyToken=...'.
The type 'System.Data.Entity.DbContext' is defined in an assembly that is not referenced. You must add a reference to assembly 'EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=...'.
Assembly B
引用 Assembly A
.实体框架仅在 Assembly A
中引用,因为 Assembly B
不使用它.Assembly B
的调用如下所示:
Assembly B
references Assembly A
. Entity Framework is referenced only in Assembly A
as Assembly B
doesn't use it. The call from Assembly B
looks like this:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
var id = AssemblyA.GetPersonId(connection, name); // compiler error
...
}
我不明白的是,如果我将 Assembly A
中的方法签名 更改为例如:
What I don't understand is that the error goes away if I change the method signature in Assembly A
to e.g.:
public static int GetPersonId(SqlConnection connection, string name, bool empty)
并将调用更改为:
var id = AssemblyA.GetPersonId(connection, name, true); // no error
为什么我的代码在第一种情况下没有编译?如错误所示,它似乎与实体框架无关.我一直认为 C# 允许方法重载,其中方法签名仅在参数类型上有所不同.例如.我可以按预期运行以下代码而不会出现问题:
Why is my code not compiling in the first case? It doesn't seem to be related to Entity Framework as the error indicates. I have always thought that C# allows method overloading where method signatures differ only in parameter types. E.g. I can run the following code without problems as expected:
static void DoStuff(int a, int b) { ... }
static void DoStuff(int a, float b) { ... }
DoStuff(10, 5);
DoStuff(10, 5.0f);
那么,尽管显然是合法的超载,为什么我的情况会出现错误?
So why am I getting the error in my situation despite the apparently legal overloads?
请注意,从 Assembly B
调用其他内部使用 EntityDataContext
的方法没有问题,唯一的区别是这些方法没有重载.
Note that from Assembly B
I have no problems calling other methods that internally use EntityDataContext
, the only difference is that these methods don't have overloads.
背景
EntityDataContext
继承 EF 的 DbContext
:
public partial class EntityDataContext : DbContext
{
public EntityDataContext() : base("name=EntityDataContext") { }
public EntityDataContext(DbConnection connection, bool contextOwnsConnection)
: base(connection, contextOwnsConnection) { }
...
}
我首先将 .NET 4.0 和 EF 6 代码用于现有数据库,并添加了一些自定义 ctor 重载.
I'm using .NET 4.0 with EF 6 code first to an existing database with some custom ctor overloads added.
推荐答案
C# 标准规定通过比较每个匹配的签名来确定哪个更适合来执行重载解析(第 7.5.3 节).它没有说明缺少引用时会发生什么,因此我们必须推断它仍然需要比较那些未引用的类型.
The C# standard specifies that overload resolution (section 7.5.3) is performed by comparing each matching signature to determine which is a better fit. It doesn't say what happens when a reference is missing, so we must infer that it still needs to compare those unreferenced types.
在您的情况下,编译器需要对 EntityDataContext
的引用才能比较两个重载.您的调用与签名完全匹配,因此理论上您不需要它,但标准没有指定任何此类短路行为.
In your case, the compiler needs a reference to EntityDataContext
to be able to compare the two overloads. Your call matches the signature exactly so in theory you shouldn't need this, but the standard doesn't specify any such short-circuit behavior.
这篇关于奇怪的“未引用程序集"尝试调用有效方法重载时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!