9

次のような暗黙の演算子を使用することに何か問題がありますか?

//linqpad c# program example
void Main()
{
    var testObject = new MyClass<int>() { Value = 1 };

    var add = 10 + testObject; //implicit conversion to int here
    add.Dump(); // 11
}

class MyClass<T>
{
    public T Value { get; set; }
    public static implicit operator T (MyClass<T> myClassToConvert)
    {
        return myClassToConvert.Value;
    }
}

このようにオブジェクトのインスタンスを値型として扱うことができると思っていたのですが、この例を見たことがないので、誰かが指摘できるようなことをしない理由があるのではないかと思いました。

私の実際のコードでは、これをデータ抽象化レイヤーの一部として実行することを考えていました。これにより、基になるデータを説明する情報を含むオブジェクトを返すことができますが、ロジックコードは、必要なときにそれを値型として扱うことができます。は値であり、同時にすべてを適切に保ち、ジェネリックスでタイプセーフにします。

4

2 に答える 2

10

次のすべてが当てはまる場合:

  • タイプのすべての可能な値MyClass<T>(値タイプでない場合を含むnull)は、次の有効な値にマップされます。T

  • 暗黙の演算子は決してスローしません(null!の場合でも)

  • 暗黙の変換は意味的に意味があり、クライアントプログラマーを混乱させることはありません

これには何の問題もありません。もちろん、これら3つのことのいずれかを実行できますが、それは悪い設計になります。特に、スローする暗黙の演算子は、呼び出された場所が呼び出されているとは言わないため、デバッグが非常に難しい場合があります。

たとえば、にT?暗黙の変換がないことを考慮してくださいTTもちろん、は値型です)。T?そのような暗黙の演算子があった場合、変換する明確な値がないため、がnullのときにスローする必要があります。これは、どの値型でもnull意味があります。T


暗黙の演算子がスローされた問題のデバッグに問題があった例を挙げましょう。

public string Foo()
{
    return some_condition ? GetSomething() : null;
}

ここでGetSomethingは、ユーザー定義の暗黙の変換を持つ、私が書いたタイプの何かを返しましたstring。私はそれが二度と戻らないことを絶対に確認しました、それでも私は!なんで?上記のコードは同等ではないためGetSomethingnullNullReferenceException

return some_condition ? (string)GetSomething() : (string)null;

しかしに

return (string)(some_condition ? GetSomething() : (Something)null);

null今、あなたはどこから来たのかを見ることができます!

于 2010-09-29T15:35:54.803 に答える
1

それは素晴らしいパターンです。型の変数として使用するにはT、明示的ににキャストするかT、型の変数に割り当てる必要があることに注意してくださいT。キャストは、メソッド呼び出しや、をとるその他のもの(追加の例など)で自動的に行われますT

割り当てなしの暗黙の変換?

于 2010-09-29T15:35:55.817 に答える