製品やフレームワークは進化します。主に、ユーザーのニーズに追いつき、新しいコンピューティング能力を活用して、単にそれをより良くするために行われます。場合によっては、主要な設計目標も製品によって異なります。 C#または.netフレームワークも例外ではありません。ご覧のとおり、現在の4番目のバージョンは、最初のバージョンと比べて非常に異なっています。しかし、物事はこの進化の後方互換性のバリケードとしてやって来ます。
ほとんどのフレームワーク/製品では、下位互換性をサポートする必要がなかった場合、機能が遮断されていました。あなたによると、C#/。netのこれらの機能は何ですか?
回答ごとに1つの機能について説明してください。
匿名メソッド。 C#2.0に選択された匿名メソッド構文は、C#3.0に追加したラムダ構文に比べて分量があることに同意していると思います。同じことを行うために2つのほぼ同じ構文を使用するのは非常に残念です。
非ジェネリックコレクションを削除します。それらは忌まわしいです...そして私がlinqを使用していて、次のようなことをしなければならない場合が多すぎます
var customObjects = container.CustomObjects.Cast<CustomObject>();
私がそれをしなければならない度に、私の魂のほんの一部が死にます。
タイプとしてのボイド。一体なぜ「ボイド」タイプなのか?インスタンスも値もありません。ジェネリック型引数、仮パラメーター型、ローカル型、フィールド型、またはプロパティ型として使用することはできません。タイプとしての意味はありません。むしろ、それはメソッド呼び出しが仮想マシンのスタックにどのような影響を与えるかという事実ですしかし、仮想マシンはそれだけです:仮想マシン。実際のマシンは戻り値をレジスター(通常はx86のEAX)に入れ、スタックにはまったく影響しません。 Void型は、あくまでも悪い考えです。
さらに悪いことに、void*
のようにポインタ型で使用すると、戻り値の型として使用する場合とはまったく異なる意味になります。これは「不明なタイプの格納場所へのポインタ」を意味し、「値を返さないメソッド」としての意味とは何の関係もありません。
void*
をポインタ型としてIntPtr
に置き換えることができます。 (およびvoid**
はIntPtr*
に置き換えられます。)戻り値の型としてのvoidを、単一の値、つまりnullを持つ型である「Unit」に置き換えることができます。 CLRの実装は、ユニット型の関数呼び出しがレジスタまたはスタックの使用を適切に最適化できると判断し、「返される」ヌルは安全に無視できることを知っています。
このような世界では、Func<A, R>
デリゲートとAction<T>
デリゲートを別々にする必要はなくなりました。 Action<T>
はFunc<T, Unit>
です。
空のステートメント;
。エラーが発生しやすく、ほとんどの場合はタイプミスがあり、{}
でまだ表現されていない追加の意味はありません。
参照タイプの配列の安全でない共分散。 IEnumerable<T>
のタイプセーフな共分散により、配列の共分散の必要性の少なくとも一部がなくなりました。 (共変の読み取り専用リストインターフェイスがある場合、それはまったく必要ありません。)
単項プラス演算子。史上最も役に立たないオペレーター。後方互換性のためにそれを保持する必要がなかった場合は、ハートビートでそれを取り出します。誰がこれを使用しているのですか?
(説明:単項プラス演算子+x
は前置インクリメント演算子ではありません++x
、ポストインクリメント演算子ではないx++
であり、2項加算演算子ではありませんx+y
。)
数値リテラルをdouble
にデフォルト設定
ほとんどのbusinessアプリでは、とにかくdecimal
の方が適切です...または、おそらくremoveデフォルトのアイデア。開発者に実際に選択を強いる。
(この「デフォルトを削除する」は、他のいくつかの場合にも適切です。たとえば、クラスをデフォルトでシールする必要があることをすべての人に説得しようとするのをあきらめましたが、think新しいクラスをシールする必要があるかどうかについて考え、明示的にします。)
私知っているさまざまなタイマークラスには大きな違いがあります。とにかく、そのうちの1つまたは2つを取り除くことはできませんでしたか?
Linqで廃止されたArray
およびList<T>
のメソッドとタイプ。次に例を示します。
Array.TrueForAll
はEnumerable.All
に置き換えることができますArray.FindAll
はEnumerable.Where
に置き換えることができますList<T>.ConvertAll
はEnumerable.Select
に置き換えることができますPredicate<T>
はFunc<T, bool>
に置き換えることができますConverter<T,R>
はFunc<T, R>
に置き換えることができますIComparer<T>
は実際にはデリゲートである必要がありますFunc<T, T, int>
非ジェネリックデリゲート非ジェネリックコレクションと同様に、非ジェネリックデリゲートは、FuncおよびActionシリーズがあるので役に立たなくなります。そして、私は3つのパラメータでバリアントを切り取っていたでしょう。 4つ以上のパラメーターがある場合は、構造を作成し、それを単一パラメーターとして使用します。イベント処理のために特定のデリゲートを宣言することは、あまりドライではありません。