はい、他の回答で示されているように、実際には多少有害です。これは主に、使用されることのないオブジェクトを割り当て、最終的にガベージコレクションする必要があるためです。しかし、もう少し詳しく説明します。
最初のインスタンスを破棄できますか?
DataSet myUPC = new DataSet();
myUPC = dbconn.getDataSet(dynSQL);
コンパイラーは、2番目の割り当ての直前に最初のインスタンスを単純に破棄しますか?
新しい未使用のインスタンスを収集するGC(ガベージコレクター)を破棄することを意味すると仮定すると、答えは次のようになります。詳細を説明させてください。
GCは、ヒープがすぐにいっぱいになるときや、ヒープの残りのスペースに収まらないオブジェクトを割り当てようとするときなど、いつでも実行できます。したがって、GCは(偶然に)最初のステートメントと2番目のステートメントの間で正確に実行される場合もあります。new DataSet()
ただし、ローカル変数にオブジェクトへの参照があるため、これはオブジェクトを収集しませんmyUPC
。オブジェクトへの参照がない場合にのみ、オブジェクトはコレクションの対象と見なされます1。
1)実際には、オブジェクトは、いわゆるルートからオブジェクトへの参照のチェーンがない場合にのみコレクションの対象と見なされます。ルートには、静的フィールド、メソッド引数、ローカル変数、および評価スタックが含まれます。
コンストラクター呼び出しを最適化できますか?
DataSet myUPC; /* Optimized away? */
myUPC = dbconn.getDataSet(dynSQL);
また、Just-In-Timeコンパイラーは、初期化されるオブジェクト以外のものに影響を与える可能性があるため(つまり、副作用があるため)、コンストラクター呼び出しを単純に最適化することはできません。たとえば、コンパイラーがコンストラクター呼び出しを最適化した場合、コンストラクターはコンソールに何も出力しません。これは望ましくないか予期されていないため、コンストラクター呼び出しはそこにとどまり、新しいインスタンスを生成する必要があります。
class MyClass
{
public MyClass()
{
Console.WriteLine("Constructor called!");
}
}
abstract class X
{
void Do()
{
MyClass my = new MyClass(); // Should always print "Constructor called!"
my = GetMyClass();
// ...
}
protected abstract MyClass GetMyClass();
}