Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
214 views
in Technique[技术] by (71.8m points)

c# - Weird "assembly not referenced" error when trying to call a valid method overload

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

When I try to call the second overload from Assembly B, VS produces the following compile-time error:

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 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
    ...
}  

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)

and change the call to:

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

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?

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.


Background

EntityDataContext inherits EF's DbContext:

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

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

        ...
}

I'm using .NET 4.0 with EF 6 code first to an existing database with some custom ctor overloads added.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...