2014-10-13 7 views
15

używam metody przeciążenia w Assembly A:Weird „Zespół nie odwołuje” błąd podczas próby wywołania w przeszłości ważne przeciążenie metody

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

Kiedy próbuję wywołać drugą przeciążenie od Assembly B, VS produkuje następujące kompilacji -czas błąd:

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 referencje Assembly A. Entity Framework jest odwoływany tylko w Assembly A jako Assembly B go nie używa. Rozmowa z Assembly B wygląda następująco:

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

Co ja nie rozumiem, jest to, że błąd zniknie, jeśli mogę zmienić metodę podpis w Assembly A do np

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

i zmienić zadzwoń pod numer:

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

Dlaczego mój kod nie kompiluje się w pierwszym przypadku? Nie wydaje się być związany z Entity Framework, jak wskazuje błąd. Zawsze uważałem, że C# umożliwia przeciążanie metod, w których sygnatury metod różnią się tylko typami parametrów. Na przykład. mogę uruchomić następujący kod bez problemów zgodnie z oczekiwaniami:

static void DoStuff(int a, int b) { ... } 
static void DoStuff(int a, float b) { ... } 

DoStuff(10, 5); 
DoStuff(10, 5.0f); 

Dlaczego otrzymuję błąd w mojej sytuacji pomimo przeciążeń najwyraźniej prawnych?

Zauważ, że od Assembly B nie mam problemów z wywołaniem innych metod, które używają wewnętrznie EntityDataContext, jedyną różnicą jest to, że te metody nie mają przeciążenia.


Tło

EntityDataContext dziedziczy EF DbContext:

public partial class EntityDataContext : DbContext 
{ 
     public EntityDataContext() : base("name=EntityDataContext") { } 

     public EntityDataContext(DbConnection connection, bool contextOwnsConnection) 
      : base(connection, contextOwnsConnection) { } 

     ... 
} 

Używam .NET 4.0 z EF 6 Kod najpierw do istniejącej bazy danych z niektórych przeciążeń niestandardowy konstruktor dodał.

Odpowiedz

7

Standard C# określa, że ​​rozdzielczość przeciążania (sekcja 7.5.3) jest wykonywana poprzez porównywanie każdej zgodnej sygnatury w celu ustalenia, która z nich jest lepiej dopasowana. Nie mówi, co dzieje się, gdy brakuje odnośnika, więc musimy wywnioskować, że wciąż musi porównywać te niezwiązane typy.

W twoim przypadku kompilator potrzebuje odniesienia do EntityDataContext, aby móc porównać dwa przeciążenia. Twoje połączenie dokładnie odpowiada sygnaturze, więc teoretycznie nie powinno ci się to podobać, ale standard nie określa takiego zachowania zwarciowego.

Powiązane problemy