web-dev-qa-db-ja.com

C#の暗黙の型変換演算子をいつ使用すればよいですか?

C#では、次のような暗黙の変換演算子をオーバーロードできます(例 [〜#〜] msdn [〜#〜] から):

struct Digit
{
    /* ... */
    public static implicit operator byte(Digit d)  // implicit digit to byte conversion operator
    {
        /* ... */
    }
}

したがって、タイプ、カスタム値タイプmagicallyを持つことができます自分自身を別の(無関係な)タイプに変換し、聴衆を戸惑いのままにします(彼らが舞台裏を覗き込み、暗黙の変換演算子を見るまで)。

私のコードを読む人を困惑させることは好きではありません。多くの人はそうは思わない。

問題は、コードを理解しにくくする暗黙の型変換演算子のユースケースは何ですか?

14
Mints97

同じ値をさまざまな方法で大まかに表すタイプ間の暗黙的な変換のみをお勧めします。例えば:

  • RGBHSLHSVCMYKなどのさまざまなカラータイプ。
  • 同じ物理量の異なる単位(MeterInch)。
  • 異なる座標系(極対デカルト)。

ただし、暗黙の変換を定義することがnotが適切である場合を示すいくつかの強力なガイドラインがあります。

  • 変換によって精度または範囲が大幅に失われる場合は、暗黙的なものであってはなりません(例:float64からfloat32へ、またはlongからintへ)。
  • 変換で(InvalidCast)例外がスローされる可能性がある場合は、暗黙的であってはなりません。
  • 変換が実行されるたびにヒープ割り当てが発生する場合は、暗黙的なものであってはなりません。
  • 変換がO(1)操作でない場合は、暗黙的に行わないでください。
  • ソースタイプまたはターゲットタイプが変更可能な場合、変換は暗黙的に行われるべきではありません。
  • 変換がなんらかのコンテキスト(データベース、カルチャ設定、構成、ファイルシステムなど)に依存している場合は、暗黙的であってはなりません(この場合、明示的な変換演算子も推奨しません)。

ここで、変換演算子_f: T1 -> T2_が上記の規則に違反していないとすると、次の動作は、変換が暗黙的である可能性があることを強く示しています。

  • _a == b_の場合はf(a) == f(b)です。
  • _a != b_の場合はf(a) != f(b)です。
  • a.ToString() == b.ToString()の場合、f(a).ToString() == f(b).ToString()になります。
  • _T1_と_T2_の両方で定義されている他の操作についても同様です。
18
Elian Ebbing

問題は、コードを理解しにくくする暗黙の型変換演算子のユースケースは何ですか?

タイプではないが(プログラマーにとって)無関係である場合。 (コードに関する限り)2つの無関係なタイプがあり、実際には(ドメインまたは合理的なプログラマに関して)関係している(まれな)シナリオがあります。

たとえば、文字列照合を行うコードがあります。一般的なシナリオは、文字列リテラルを照合することです。 IsMatch(input, new Literal("some string"))を呼び出すのではなく、暗黙的な変換により、その式(コード内のノイズ)を取り除き、文字列リテラルに焦点を合わせることができます。

ほとんどのプログラマーはIsMatch(input, "some string")を見て、何が行われているのかすぐにわかります。これにより、呼び出しサイトでコードが明確になります。要するに、それはwhatが起こっていることを少し理解しやすくします--howが起こっていることを少し犠牲にしてください。

ここで、同じことを行う単純な関数オーバーロードの方が良いと主張するかもしれません。そしてそうです。しかし、この種のことがユビキタスである場合、1つの変換を行う方が、関数のオーバーロードを山積みするよりもクリーン(コードが少なく、一貫性が向上)です。

また、プログラマーに中間タイプを明示的に作成して「実際に何が起こっているのか」を確認するようにプログラマーに要求する方がよいと主張するかもしれません。それは簡単ではありません。個人的には、リテラル文字列の一致の例は「実際に何が起こっているのか」について非常に明確であると思います。プログラマはhowの仕組みを知る必要はありません。コードが実行されているさまざまなプロセッサによってすべてのコードがどのように実行されるか知っていますか?プログラマがhowについて気にかけるのをやめる抽象化の行が常にあります。暗黙的な変換手順が重要であると思われる場合は、暗黙的な変換を使用しないでください。彼らがコンピュータを幸せに保つための儀式であり、プログラマがどこでもそのノイズを見ないほうがいいと思うなら、それを考慮してください。

6
Telastyn