Ambiguous delegate construction #9426
Unanswered
richard-fine
asked this question in
Q&A
Replies: 1 comment 5 replies
-
Can you post the entire code sample that does not compile? Following your post I come up with the following that compiles just fine: class C
{
void Repro()
{
AddHandler(MyHandler);
}
public struct ObjectId
{
public int Value;
public static implicit operator ObjectId(int i) => new ObjectId { Value = i };
}
void MyHandler(int objectId) => Console.WriteLine(objectId);
public delegate void Handler(int objectId);
public delegate void HandlerExplicit(ObjectId e);
public static void AddHandler(Handler a) { }
public static void AddHandler(HandlerExplicit b) { }
} |
Beta Was this translation helpful? Give feedback.
5 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I'm on a project where we're migrating some API from primitive types to more domain-specific types. We want to provide implicit conversion so that code using the existing API is able to continue working without changes. In general this is working nicely, but we've run into an interesting case around delegates that I'm wondering if anyone could help me understand more clearly.
So, our old code is using
int
to represent a common concept (an object identifier). In some parts of our API we have a callback registration setup using a delegate, like this:Users can then declare a method and register it as a handler:
So far so good. Now, in the new version of our API, we're introducing a dedicated type to represent the object identifier. We give it an implicit conversion from
int
so that customers who are storing these identifiers inint
-typed fields don't get errors - we want them to have source-level compatibility (for now - eventually we'll remove the conversions and require they use the dedicated type exclusively). So we introduce:We want to introduce a new overload of
AddHandler
, rather than changing the existing one, so that we also have binary compatibility, i.e. precompiled libraries using the API can still resolve references to and call the old method (which will then forward to the new method).However, this doesn't quite work:
I'm surprised to see this, because if I try to explicitly use
MyHandler
to construct aHandler
delegate instance:That makes sense, because I wouldn't expect the delegate to do any conversion of parameters before invoking the method. But as such - why, when I don't specify the delegate type, is it considered ambiguous?
Beta Was this translation helpful? Give feedback.
All reactions