Ambiguous implicit operators - int and double

D

dave_henderson1

I currently have the following code:

struct DoubleWrapper
{
public DoubleWrapper(double doubleValue) {}
public static implicit operator DoubleWrapper(double doubleValue)
{ return new DoubleWrapper(doubleValue); }
}

struct IntegerWrapper
{
public IntegerWrapper(int intValue) {}
public static implicit operator IntegerWrapper(int intValue)
{ return new IntegerWrapper(intValue); }
}

class MyClass
{
public void MyMethod(DoubleWrapper doubleValue) {}
public void MyMethod(IntegerWrapper intValue) {}

static void Main()
{
MyClass myClass = new MyClass();
myClass.MyMethod(1);
}
}

The code doesn't compile, outputting the following error:
error CS0121: The call is ambiguous between the following methods or
properties:
'ConsoleApplication1.MyClass.MyMethod(ConsoleApplication1.IntegerWrapper)'
and
'ConsoleApplication1.MyClass.MyMethod(ConsoleApplication1.DoubleWrapper)'

I thought it might be because the compiler couldn't tell if 1 was an
int or a double, but if i replace the two MyMethod() methods by
changing the types as follows, it works:

public void MyMethod(double doubleValue) {}
public void MyMethod(int intValue) {}
Can someone explain why my code produces that error?
Thanks
 
J

Jon Skeet [C# MVP]

I currently have the following code:

The code doesn't compile, outputting the following error:
error CS0121: The call is ambiguous between the following methods or
properties:
'ConsoleApplication1.MyClass.MyMethod(ConsoleApplication1.IntegerWrapper)'
and
'ConsoleApplication1.MyClass.MyMethod(ConsoleApplication1.DoubleWrapper)'

I thought it might be because the compiler couldn't tell if 1 was an
int or a double, but if i replace the two MyMethod() methods by
changing the types as follows, it works:

public void MyMethod(double doubleValue) {}
public void MyMethod(int intValue) {}
Can someone explain why my code produces that error?

I believe it's because neither method is more specific than the other,
and both are applicable. When you use straight int/double, the int
version is more applicable because no conversion is involved - but I
don't think the compiler sees any difference between

int -> IntegerWrapper
and
int -> double -> DoubleWrapper

At a guess, anyway.

If you manually cast 1 to the wrapper you want to use, it's fine.
 
G

Guest

I don't think the compiler sees any difference between
int -> IntegerWrapper
and
int -> double -> DoubleWrapper

I agree with Jon here - I think the term they use is "better" that is,
neither of these two conversions is better than the other so the compiler
will not choose between them. Section 7.4.2.3 in the C# spec lays out the
rules.

I believe that the int->double part of the conversion is not really
significant here - the compiler is comparing the double->DoubleWrapper and
int->IntWrapper conversions against each other and finds neither is better.

It is interesting to notice that if you use a double in your client code,
then it compiles and binds to the double->DoubleWrapper converter. I think
this one works because the int->IntWrapper converter is no longer applicable
because it would require the compiler to add an explicit conversion from
double->int in order to call it. And since our client code does not have a
cast, the compiler is not authorized to use explicit conversions to try to
match a type converter.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top