.NET中不明确的隐式用户定义转换

时间:2014-09-10 21:48:36

标签: c# .net implicit-conversion

我最近在.NET中编写了几个结构,然后我添加了隐式转换运算符

示例:

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

测试

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'

我想知道C#中隐式转换的规则/最佳实践是什么?

自我注意:我的直觉是类型不应该通过隐式转换返回其他类型的对象?即Beta不应通过隐式转换返回Alpha,反之亦然,Beta应返回BetaAlpha应返回Alpha }

示例(已修复):

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

我的假设是否正确?

2 个答案:

答案 0 :(得分:5)

在这两个类中都定义了Alpha(Beta x),因此应该使用哪一个是不明确的。 允许每个类仅处理转换为自身。换句话说,struct Alpha实现Alpha(Beta b),因为它最好知道如何创建自己的实例。另外,我会考虑实现显式转换而不是隐式转换。它有时可能会意外地导致错误或意外转换,并且在处理复杂类时通常会进行“有损”转换。

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

唯一一次你可能在一个课程中实现“双向”,就是如果另一个班级不了解你的新班级。这是你想要的更常见的场景。支持转换为来自预先存在的类/结构,例如支持从框架类型转换为:

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

答案 1 :(得分:0)

不,你的假设是不正确的(即使你写了工作代码)。您的代码中的问题是您已在两个类中定义了相同的转换运算符,这就是它们不明确的原因;编译器无法决定使用哪一个。

您可以在C#4.0语言规范的section 6.4.3 (Evaluation of user-defined conversions)中阅读更多内容。