ここでのほとんどの回答は、要点を見逃しているようです。ポリモーフィズムは、インスタンス間だけでなく、型間でも使用できます。これは、ジェネリックを使用するときに必要になることがよくあります。
ジェネリック メソッドに型パラメーターがあり、それを操作する必要があるとします。コンストラクターを認識していないため、インスタンス化したくありません。
例えば:
Repository GetRepository<T>()
{
//need to call T.IsQueryable, but can't!!!
//need to call T.RowCount
//need to call T.DoSomeStaticMath(int param)
}
...
var r = GetRepository<Customer>()
残念ながら、「醜い」代替案しか思いつきません。
醜いリフレクションを使用し
、インターフェイスとポリモーフィズムのアイデアを打ち負かします。
完全に別のファクトリ クラスを作成する
これにより、コードの複雑さが大幅に増加する可能性があります。たとえば、ドメイン オブジェクトをモデル化しようとしている場合、各オブジェクトには別のリポジトリ クラスが必要になります。
インスタンス化してから、目的のインターフェイス メソッドを呼び出す
これは、ジェネリック パラメーターとして使用されるクラスのソースを制御したとしても、実装が難しい場合があります。その理由は、たとえば、インスタンスがよく知られている「DB に接続されている」状態のみである必要がある場合があるためです。
例:
public class Customer
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
void SomeOtherMethod()
{
//do work...
}
}
インスタンス化を使用して静的インターフェースの問題を解決するには、次のことを行う必要があります。
public class Customer: IDoSomeStaticMath
{
//create new customer
public Customer(Transaction t) { ... }
//open existing customer
public Customer(Transaction t, int id) { ... }
//dummy instance
public Customer() { IsDummy = true; }
int DoSomeStaticMath(int a) { }
void SomeOtherMethod()
{
if(!IsDummy)
{
//do work...
}
}
}
これは明らかに見苦しく、また不必要なことで、他のすべてのメソッドのコードが複雑になります。明らかに、エレガントなソリューションでもありません!