Ошибка при попытке вызвать допустимый метод перегрузки
Я использую перегрузку метода в 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, как указывает ошибка. Я всегда думал, что С# допускает перегрузку метода, когда сигнатуры методов различаются только по типам параметров. Например. Я могу запустить следующий код без проблем, как ожидалось:
static void DoStuff(int a, int b) { ... }
static void DoStuff(int a, float b) { ... }
DoStuff(10, 5);
DoStuff(10, 5.0f);
Итак, почему я получаю ошибку в своей ситуации, несмотря на явно законные перегрузки?
Обратите внимание, что из Assembly B
у меня нет проблем с вызовом других методов, которые внутренне используют EntityDataContext
, единственное отличие состоит в том, что эти методы не имеют перегрузок.
Фон
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.
Ответы
Ответ 1
В стандарте С# указано, что разрешение перегрузки (раздел 7.5.3) выполняется путем сравнения каждой согласованной сигнатуры, чтобы определить, какая из них лучше подходит. Он не говорит, что происходит, когда ссылка отсутствует, поэтому мы должны сделать вывод о том, что по-прежнему необходимо сравнивать эти неопубликованные типы.
В вашем случае компилятору нужна ссылка на EntityDataContext
, чтобы сравнить две перегрузки. Ваш вызов точно совпадает с подписью, поэтому теоретически вам это не нужно, но стандарт не указывает на такое поведение короткого замыкания.