Object
私の同僚は、.NET 2.0 以降では、変数を宣言したり、パラメーターを返したりするときに使用する必要はまったくないと主張しました。
彼はさらに進んで、そのようなすべての場合において、代替品としてジェネリックを使用すべきであると述べました.
この主張に妥当性はありますか?頭のてっぺんから、Object
同時スレッドをロックするために使用しています...
ジェネリックはobject
多くの場合に勝りますが、型がわかっている場合に限られます。
タイプ - がわからない場合object
や、他の関連する基本タイプがそれらのインスタンスの答えである場合がまだあります。
例えば:
object o = Activator.CreateInstance("Some type in an unreferenced assembly");
その結果をキャストすることはできず、コンパイル時に型が何であるかを知ることさえできないためobject
、有効な使用法です。
あなたの同僚は一般化しすぎています - おそらくこの質問を彼に向けてください. ジェネリックは素晴らしいです、彼にそれだけを与えますが、それらは「置き換え」ませんobject
.
object
ロックに最適です。ジェネリックを使用すると、適切に型付けされたままにすることができます。インターフェイスまたは基本クラスに制約することもできます。でそれを行うことはできませんobject
。
このことを考慮:
void DoSomething(object foo)
{
foo.DoFoo();
}
キャストなしでは機能しません。でもジェネリックで…
void DoSomething<T>(T foo) where T : IHasDoFoo
{
foo.DoFoo();
}
C# 4.0 とdynamic
では、これをランタイムに任せることができますが、実際にはその必要性は見られませんでした。
void DoSomething(dynamic foo)
{
foo.DoFoo();
}
COM との相互運用を使用する場合、常に選択肢があるとは限りません... ジェネリックは、相互運用の問題に実際には対応していません。
Object
@Daniel A. Whiteが彼の回答で述べたようにlock
、a の最も軽量なオプションでもあります。
はい、有効性があります。ここでは、すでに適切な内訳が行われています。
ただし、オブジェクトをまったく使用しないインスタンスがないかどうかは確認できませんが、個人的にはオブジェクトを使用せず、ジェネリックの前でさえ、ボックス化/ボックス化解除を避けました.
あなたが言及したものを含め、同期のためにオブジェクトを使用する多くの反例があります。
もう 1 つの例は、DataSource
さまざまなオブジェクト タイプのいずれかに設定できる、データ バインディングで使用されるプロパティです。
大まかな反例: System.Collections 名前空間は .NET 4 でも健在であり、MSDN での使用に対する非推奨や警告の兆候はありません。そこにあるメソッドは、オブジェクトを受け取って返します。
この質問には、実際には次の 2 つの質問が含まれています。
型の格納場所はObject
、その型のインスタンスへの参照を保持する必要がある場合に使用する必要があります (そのようなインスタンスへの参照は他の型では保持できないため)。それを超えて、単一の有用な共通基本型を持たないオブジェクトへの参照を保持する場合に使用する必要があります。これは、リフレクションを使用する多くのシナリオ (オブジェクトの型が実行時に計算された文字列に依存する可能性がある場合) で明らかに当てはまりますが、コンパイル時に型がわかっているものが取り込まれた特定の種類のコレクションにも適用できます。string
簡単な例として、 のシーケンスによってインデックス付けされた の階層コレクションを表すには、int
各ノードを 型Object
にし、 aString
またはObject[]
. Object[]
このようなコレクションから項目を読み取るのは、各項目を調べてそれがまたはのインスタンスであるかどうかを判断する必要があるため、やや扱いにくいですが、String
オブジェクト インスタンスのみが文字列または配列のいずれかを保持していたもの。Node
type のフィールドと type のフィールドを持つ型をString
定義することも、派生型( type のフィールドを含む) と( type のフィールドを持つ) を持つNode[]
抽象型を定義することもできますが、そのようなアプローチでは、使用されるヒープ オブジェクトの数が増加します。特定のデータセットを保持します。Node
StringNode
String
ArrayNode
Node[]
一般に、取得されるオブジェクトのタイプがコレクションに押し込まれたものに依存しないようにコレクションを設計する方が良いことに注意してください (おそらく、さまざまなタイプに対して「並列コレクション」を使用します)。ただし、すべてが意味的にうまくいくわけではありません。
type のインスタンスに関しては、から継承するObject
ようなものと呼ばれる封印された型によって十分に満足されない、それらが果たすことができる役割があるかどうかはわかりません。唯一の目的が一意のトークンであるオブジェクト インスタンスがあると便利な状況がいくつかあります。概念的には、次のように言った方が適切かもしれません。TokenObject
Object
TokenObject myLock = 新しい TokenObject;
言うより
オブジェクト myLock = 新しいオブジェクト;
前の宣言は、宣言された変数がトークン オブジェクト以外のものを保持するために使用されることは決してないことを明確にするためです。Object
それにもかかわらず、一般的な慣例は、オブジェクトに関して重要なのは、その参照がプログラムの存続期間を通じて一意であるということだけである場合に、型のインスタンスを使用することです。