使用<时支持哪些隐式转换?和>运营商?

时间:2015-04-29 08:54:28

标签: c# implicit-conversion

我有一个结构:

public struct Decibel
{
    public readonly double Value;

    public Decibel (double value)
    {
        Value = value;
    }

    public static implicit operator Decibel (double decibels)
    {
        return new Decibel (decibels);
    }

    public static implicit operator double (Decibel decibels)
    {
        return decibels.Value;
    }
}

现在我可以做到:

bool x = new Decibel (0) < new Decibel (1);

编译器似乎足够聪明,可以将Decibel转换为double,然后使用<运算符进行双打?

我有不同的struct名为Duration,它正在包裹TimeSpan。它有TimeSpan到/ Duration的隐式转换,但<>运算符不适合它。

c#是否只识别基元类型之间的转换?

1 个答案:

答案 0 :(得分:3)

首先请注意,C#将允许在类型之间进行最多一次隐式的用户定义转换。

因此,当您比较Decibel的两个实例时,编译器会发现它可以使用用户定义的隐式转换将Decibel转换为要与之比较的double。< / p>

但是,当您比较Duration的两个实例时,编译器找不到任何可用于进行比较的隐式转换。对于可以隐式转换类型的任何类型,编译器不会考虑任何用户定义的比较运算符。它只会查找可以隐式转换类型的任何类型的内置比较运算符。

因此,即使TimeSpan提供了理论上可以使用的用户定义的比较运算符,编译器也不会使用隐式转换为TimeSpan

另请注意,即使TimeSpan类提供了对double的隐式转换,编译器仍然不会使用它,因为它只会考虑链中最多一个隐式的用户定义转换隐式转换。

换句话说,鉴于这些结构:

public struct Number
{
    public readonly double Value;

    public Number(double value)
    {
        Value = value;
    }

    public static implicit operator Number(double duration)
    {
        return new Number(duration);
    }

    public static implicit operator double(Number number)
    {
        return number.Value;
    }
}

public struct NumberWrapper
{
    public readonly Number Value;

    public NumberWrapper(Number value)
    {
        Value = value;
    }

    public static implicit operator NumberWrapper(Number duration)
    {
        return new NumberWrapper(duration);
    }

    public static implicit operator Number(NumberWrapper number)
    {
        return number.Value;
    }
}

此代码将编译:

bool x = new Number(1) < new Number(2);

所以当然会这样:

Number n1 = new NumberWrapper(1);
Number n2 = new NumberWrapper(2);
bool z = n1 < n2;

但这不会:

bool y = new NumberWrapper(1) < new NumberWrapper(2);

因为NumberWrapper没有任何支持<的类型的隐式转换,而没有任何进一步的隐式转换。

请注意,所有原始数字和枚举类型(例如char,short,int,long,float,double,decimal,enum)都提供内置的比较运算符。所有其他类型只能提供用户定义的比较运算符。

用户定义的比较运算符如下所示:

public static bool operator < (MyType lhs, MyType rhs) ...