Ambiguous implicit user defined conversions in .NET

这一生的挚爱 提交于 2021-02-10 20:15:08

问题


I recently wrote a couple of structs in .NET, to which I then added implicit conversion operators

Example:

public struct Alpha
{
    internal string value;

    public static implicit operator Alpha(Beta b)
    {
        return new Alpha() { value = b.value };
    }

    public static implicit operator Beta(Alpha a)
    {
        return new Beta() { value = a.value };
    }
}

public struct Beta
{
    internal string value;

    public static implicit operator Alpha(Beta b)
    {
        return new Alpha() { value = b.value };
    }

    public static implicit operator Beta(Alpha a)
    {
        return new Beta() { value = a.value };
    }
}

Test:

Alpha a = default(Alpha);
Beta b = a;
// Ambiguous user defined conversions 'Alpha.implicit operator Beta(Alpha)' and 'Beta.implicit operator Beta(Alpha)' when converting from 'Alpha' to 'Beta'

I would like to know what the rules / best practices are surrounding implicit conversion in C#?

Note to self: My gut feeling is that types should not return objects of another type through implicit conversion? i.e. Beta should not return Alpha via implicit conversion, and vice-versa, however, Beta should return Beta, and Alpha should return Alpha

Example (fixed):

public struct Alpha
{
    internal string value;

    public static implicit operator Alpha(Beta b)
    {
        return new Alpha() { value = b.value };
    }
}

public struct Beta
{
    internal string value;

    public static implicit operator Beta(Alpha a)
    {
        return new Beta() { value = a.value };
    }
}

Is my assumption correct?


回答1:


You have a Alpha(Beta x) defined in both classes, thus it is ambiguous which one should be used. Allow each class to handle only the conversion to itself. In other words, struct Alpha implements Alpha(Beta b) because it best knows how to create an instance of itself. Also, I would consider implementing explicit conversions instead of implicit. It can sometimes cause bugs or unexpected conversions accidentally, and when dealing with complex classes are often "lossy" conversions.

public struct Alpha
{
    internal string value;

    public static implicit operator Alpha(Beta b)
    {
        return new Alpha() { value = b.value };
    }
}

public struct Beta
{
    internal string value;

    public static implicit operator Beta(Alpha a)
    {
        return new Beta() { value = a.value };
    }
}

The only time you'd likely implement "both ways" in a single class, is if the other class has no knowledge of your new class. This is the more common scenario when you want to support conversion to-from a pre-existing class/struct such as supporting conversion to-from a framework type:

public struct Alpha
{
    internal string value;

    public static implicit operator Alpha(string b)
    {
        return new Alpha() { value = b };
    }

    public static implicit operator string(Alpha a)
    {
        return  a.value;
    }
}



回答2:


No, your assumpion is not correct (even though you wrote working code thanks to it). The problem in your code is that you have defined the same conversion operators in both classes, this is why they are ambiguous; the compiler cannot decide which one to use.

You can read more in section 6.4.3 (Evaluation of user-defined conversions) of the C# 4.0 Language Specification.



来源:https://stackoverflow.com/questions/25775645/ambiguous-implicit-user-defined-conversions-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!