2

演算子のオーバーロード、特に暗黙的および明示的な変換を使用して大規模な作業を行ったことはありません。

ただし、頻繁に使用される数値パラメーターがいくつかあるため、これらのパラメーターを厳密に型指定するために、数値型のラッパーとして構造体を作成しています。実装例を次に示します。

public struct Parameter
{
    private Byte _value;
    public Byte Value { get { return _value; } }

    public Parameter(Byte value)
    {
        _value = value;
    }

    // other methods (GetHashCode, Equals, ToString, etc)

    public static implicit operator Byte(Parameter value)
    {
        return value._value;
    }
    public static implicit operator Parameter(Byte value)
    {
        return new Parameter(value);
    }

    public static explicit operator Int16(Parameter value)
    {
        return value._value;
    }
    public static explicit operator Parameter(Int16 value)
    {
        return new Parameter((Byte)value);
    }
}

Int64明示的および暗黙的な演算子のコツをつかむためにテスト実装を試していたときに、 aを自分の型に明示的にキャストしようとしましたParameterが、驚いたことに、例外はスローされませんでした。さらに驚くべきことに、数値が切り捨てられ、進みました。カスタムの明示的な演算子を除外しようとしましたが、それでも同じように動作しました。

public void TestCast()
{
    try
    {
        var i = 12000000146;
        var p = (Parameter)i;
        var d = (Double)p;

        Console.WriteLine(i);   //Writes 12000000146
        Console.WriteLine(p);   //Writes 146
        Console.WriteLine(d);   //Writes 146
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);  //Code not reached
    }
}

したがって、構造体の代わりにプレーンを使用して実験を繰り返しByteましたが、まったく同じ動作をしているため、明らかにこれは予想される動作ですが、データが失われる明示的なキャストは例外をスローすると考えました。

4

2 に答える 2

7

コンパイラが明示的なユーザー定義の変換を分析している場合、変換の「どちらか一方」(または両方) に明示的な組み込み変換を配置できます。たとえば、int から Fred へのユーザー定義の変換があり、次のようになっているとします。

int? x = whatever;
Fred f = (Fred)x;

次に、コンパイラは「int から Fred への明示的な変換があるので、int から int への明示的な変換を行ってから、int を Fred に変換できます。

あなたの例では、ロングからショートへの組み込みの明示的な変換があり、ショートからパラメーターへのユーザー定義の明示的な変換があるため、ロングからパラメーターへの変換は合法です。

同じことが暗黙の変換にも当てはまります。コンパイラは、ユーザー定義の暗黙的な変換の両側に組み込みの暗黙的な変換を挿入する場合があります。

コンパイラは、2 つのユーザー定義の変換を連鎖させることはありません。

独自の明示的な変換を正しく構築することは、C# では困難な作業です。変換をカバーする仕様の章全体を完全かつ深く理解するまで、そうすることをやめることをお勧めします。

連鎖変換のいくつかの興味深い側面については、この件に関する私の記事を参照してください。

于 2011-12-16T04:34:08.987 に答える
3

この目標:

したがって、これらのパラメーターを厳密に型指定するために、数値型のラッパーとして構造体を作成しています

そして、このコード:

public static implicit operator Byte(Parameter value)
{
    return value._value;
}
public static implicit operator Parameter(Byte value)
{
    return new Parameter(value);
}

完全に矛盾しています。双方向の暗黙的な演算子を追加することで、ラッパーがもたらす可能性のある型安全性を無効にします。

したがって、暗黙的な変換を削除します。それらを明示的なものに変更できます。

于 2011-12-15T21:13:35.740 に答える