C#で動的型を使用する場合の欠点


14

私は最近、C#の動的型についてさらに研究しています。コードをコンパイルすると理解できる例がいくつかありますが、コードを再コンパイルする必要はありませんが、直接実行できます

実際にデータ型を自由に変更できるというキーワードが提供する柔軟性は大きな利点であると感じています。

質問、

開発者が実装を開始する前に知っておく必要がある実行時例外スローする間違った動的メソッド呼び出し以外に、特定の欠点がありますか


3
C#3では、object型キャストの使用または直接型キャストはコード臭と常に考えていました。ほとんどすべての場合、それは私または私のチームの1人がその機能に適したインターフェースを設計していなかったことを意味します。今C#4を使用している場合、使用方法についてもほぼ同じように感じると思いdynamicます。すべてを動的にすると、そのケースを見ることができますが、その場合は、最初に動的型付け言語を選択した可能性もあります。* 8 ')
マークブース

パースペクティブについては@MarkBooth +1。その後、C#を使用したコアの実装は、4.0で動的型を導入しても、引き続き強く型付けされたままになると言っても安全ですか
Karthik Sreenivasan

dynamicC#で使用するということは、必要なのがコードのごく一部の動的な型付けだけであれば、IronPythonにドロップアウトする必要がないということです。式エバリュエーターの場合、式dynamicのオペランドと評価の結果を表すのに非常に成功しました。
エドジェームズ

@EdJames -の偉大な使用のようなその音dynamicに加えて、私は私がネットで開発していたとき、私はIronPythonのについて知ってよかっ-それは我々がやろうとした特定の物事作っている可能性が非常に簡単に。
マークブース

回答:


16

主な欠点は、C#の主要なプロパティの1つ(必ずしも利点ではない)を捨てることです-静的に型付けされていること(およびほとんどの場合型安全)。

動的型付けの問題は、コンパイル中に明らかになるバグをしばしば隠すことです。そのようなバグは実行時にのみ現れるため、もちろん検出がはるかに難しくなります。

C#で動的型付けを使用するIMOの理由はほとんどありません。主な理由は、動的型付け言語とのコラボレーションです(これが最初に動的型が導入された理由です)。

完全に動的に型付けされたプログラミングを行いたい場合は、C#を動的にハックするのではなく、動的に設計された言語を検討する必要があります。.Netライブラリを使用する場合は、たとえばIronPythonを使用できます。


IronPythonの場合は+1。これは、長期的にはメンテナンスの問題につながる可能性があることを意味します。
カルティクスリーニバサン

6
dynamicあなたに与えられる大きなことは、どんな種類のリフレクションハックもなしにオブジェクトを実際の型にアップキャストできることです。たとえばBase foo = new Derived();と2つのオーバーロードされたメソッドがあったMoo(Base x)Moo(Derived x)、その後Moo(foo)の呼び出しMoo(Base x)が、Moo((dynamic)foo)呼び出しがMoo(Derived x)。これにより、たとえばcode.logos.com/blog/2010/03/…など、Visitorパターンの非常にエレガントな実装が可能になります。これは一般に非常に強力な手法です。

@TheMouthofaCowニース、確かにダイナミックのための他のいくつかの「正当な」使用法もありますが、これらは少数であり、その中間にあります(そして、あなたはこのようなことを試みる前にあなたがしていることを確実に知る必要があります)。
マテイZábský

@TheMouthofaCow注意すべき比較的新しいデザインパターン(訪問者パターン)。ありがとう。
カルティクスリーニバサン

1
はい、それはかなりクールです。先週私は独自にそれを思いついたので、それがC#兵器庫に採用された受け入れられたアイデアであることを見るのは嬉しかったです。

9

どんな種類の欠点を探しているのかわかりませんがdynamic、静的型付けで機能するが、では機能しない機能について知りたい場合はほとんどありません。

  1. 拡張メソッドは機能しません。これはおそらく最大のものです。持っている場合dynamic collection、次のようなコードは使用できませんcollection.Distinct()。これは、利用可能な拡張メソッドが名前空間に依存してusingおり、DLRがそれらを知る方法がないためです。

    回避策として、通常の静的メソッドであるかのようにメソッドを呼び出すことができますEnumerable.Distinct(collection)。または、コレクションのタイプをのようなものに変更できますIEnumerable<dynamic>

  2. foreachが必要IEnumerableです。通常のC#では、foreachパターンベースです。つまり、特定のインターフェイスは必要なく、GetEnumerator()適切なオブジェクトを返すメソッドだけが必要です。foreachon を使用する場合dynamic、の実装IEnumerableが必要です。しかし、この動作の理由はC#1.0にジェネリックがないため、この「欠点」はほとんど無関係です。


拡張メソッドの場合は+1。これは、GroupBy()などの他のLINQクエリ演算子にも適用されますか?
カルティクスリーニバサン

2
@Karthik:はい。拡張メソッドはコンパイル時のシンタックスシュガーだと思うので、解決されないという事実があります。

@TheMouthofaCow +1-説明をありがとう。
カルティクスリーニバサン

1
拡張メソッドに同意します。つまり、実行時に動的メソッドが拡張メソッドを特定できないのに、説明した動的コレクションを追跡できませんでした。
カルティクスリーニバサン

7

.netの動的型動的として宣言された変数ではない)の問題は、静的型で使用できる機能の多くがないことです。

  • リフレクションはありません(メンバーを反復処理できますが、それ以外のことはできません)
  • メタデータなし(ダイナミックデータサイト/ mvcで検証が行われます)
  • コンパイル時には絶対にチェックしません(スペルミスは検出されません)
  • これは強力な機能であるため、初心者はそれを悪用/誤用/誤解する傾向があります。
  • 動的な型で記述されたコードは、維持が難しく、リファクタリングが難しい傾向があります
  • アヒルのタイピングやその他の機能のため、達人は誰にも読めないコードを書くかもしれない

そのため、自分が何をしているかわからない限り、動的型でコードを書かないでください。


6

dynamicマークされobjectているだけなので、値タイプをボックス化します。

これはパフォーマンスに影響する可能性がありますが、とにかくパフォーマンスが重要なコードで静的型付けを使用するため、実際にはおそらく問題ではありません。

このボックス化は、可変値タイプにも干渉します。あなたがそれらを変更した場合dynamic、あなただけの箱入りのコピーを変更します。ただし、そもそも可変値型を使用するべきではないため、これも大きな問題ではありません。


+1私は間違いなく同意します。静的な型指定は、パフォーマンスが重要なコードに最適なアプローチです。
カルティクスリーニバサン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.