19

そのため、正しく理解できなかったメソッド内にラムダ式または無名メソッドを作成するたびに、それを修正するために、アプリケーション全体または単体テストフレームワーク全体を再コンパイルして再起動する必要がありますこれは非常に煩わしいことであり、そもそもこれらの構成を使用して節約したよりも多くの時間を無駄にすることになります。Linqとラムダは私のお気に入りのC#機能のひとつですが、できればそれらから離れようとするのはとても悪いことです。

それがこのようになっているのには技術的な理由があると思いますが、おそらく誰かが知っていますか?さらに、VS2010で修正されるかどうか誰かが知っていますか?

ありがとう。

4

4 に答える 4

20

はい、これができないのには非常に正当な理由があります。単純な理由はコストです。C#(またはVB)でこの機能を有効にすると、コストが非常に高くなります。

ラムダ関数の編集は、現在のENC(Edit'n'Continue)アーキテクチャでは解決が非常に難しいENC問題のクラスの特定のケースです。つまり、ENCが次のいずれかを実行する方法をENCすることは非常に困難です。

  1. クラスの形式でメタデータを生成します
  2. ジェネリックメソッドを編集または生成します

最初の問題は論理的な制約ですが、ENCアーキテクチャのいくつかの制限にもぶつかります。つまり、問題はファーストクラスを生成することはそれほど難しいことではないということです。面倒なのは、2回目の編集後にクラスを生成することです。ENCエンジンは、ライブコードだけでなく、生成されたクラスのシンボルテーブルの追跡を開始する必要があります。通常、これはそれほど悪くはありませんが、生成されたクラスの形状がそれが使用されるコンテキストに基づいている場合(クロージャのためのラムダの場合のように)、これはますます困難になります。さらに重要なことに、プロセスですでに生きているクラスのインスタンスとの違いをどのように解決しますか?

2番目の問題は、CLRENCアーキテクチャの厳密な制限です。これを回避するためにC#(またはVB)でできることは何もありません。

残念ながら、ラムダはこれらの問題の両方に真っ向からぶつかりました。短いバージョンでは、ラムダのENCには、既存のクラス(他のENCから生成された場合とされていない場合があります)に対する多くのミューテーションが含まれます。大きな問題は、現在のプロセススペースで生きている新しいコードと既存のクロージャーインスタンスの違いを解決することです。また、ラムダは他のコードよりもジェネリックを多く使用する傾向があり、問題#2にぶつかります。

詳細はかなり毛深いですし、通常のSOの答えには少し複雑すぎます。私はこのテーマについて長いブログ投稿を書くことを検討しました。私がそれに近づいたら、私はそれをこの特定の答えにリンクし直します。

于 2009-02-24T15:15:49.777 に答える
1

サポートされているコードの変更のリストによると、既存の型にフィールドを追加することはできません。匿名メソッドは、奇妙な名前のクラス (ちょっと<>_c__DisplayClass1) にコンパイルされます。匿名メソッドへの変更には、囲まれた変数のセットの変更が含まれていない場合がありますが (これらを追加すると、既存のクラスのフィールドが変更されます)、匿名メソッドを変更できないのはそのためだと思います。

于 2009-02-24T14:56:04.300 に答える
1

この機能が VB では部分的にサポートされているのに、C# ではサポートされていないのは少し残念です: http://msdn.microsoft.com/en-us/library/bb385795.aspx

C# で同じ動作を実装すると、ラムダ式を含む関数の痛みのレベルが 80% 軽減されます。ラムダ式やそれに依存する式を変更する必要はなく、おそらく「モンスター コスト」も必要ありません。

于 2011-05-25T16:33:55.963 に答える
0

単体テストの再起動には、数秒かかるはずです。正直なところ、「編集して続行」モデルが好きではありませんでした.実行途中の変更が以前に実行されたコードに影響を与えた場合に備えて、常に最初から再実行する必要があります. それを考えると、非常に迅速なターンアラウンドで実行できる単体テストを使用することをお勧めします。個々の単体テストの開始に耐えられないほどの時間がかかる場合は、対処を検討する必要があります。

編集:なぜ機能しないのかについては、一部のラムダでは機能するが、他のラムダでは機能しない場合があります。変数 ( を含む) をキャプチャしないラムダ式thisは、プライベートな静的変数にキャッシュされるため、デリゲートのインスタンスは 1 つだけ作成されます。コードを変更するということは、その変数を再初期化することを意味し、興味深い副作用があると思われます。

于 2009-02-24T14:50:16.000 に答える