2012-02-08 5 views
1

私は生態系のシミュレーションを行っています。それはとても簡単なので、現実感は心配しないでください。 が再生方法は、生物クラスに位置しており、それは生物である戻り値の型を除いて、クラスの工場で正確に使用することができます戻り値の型を現在のクラスにする方法は、サブクラスで使用されます

public Organism Reproduce() 
    { 
     double[] copy = new double[genes.Count]; 
     for(int i = 0; i < copy.Length; i++) 
      // 10% chance to mutate, change up to 10% 
      copy[i] = genes[i] + (Program.rand.Next(10) < 1 ? 
       genes[i] * 0.2 * (Program.rand.NextDouble() - 0.5) : 0.0); 
     return new Organism(genes); 
    } 

私はRubyで、それはので、もし「自己」を返すことが可能です知っていますこのメソッドはこのメソッドを継承するクラスによって使用され、メソッドは継承するクラスのオブジェクトを返します。

問題は次のとおりです。このメソッドを変更して、プラントから呼び出されたときにプラントを作成して返すようにするにはどうすればよいですか?

答えて

4

ジェネリックを使用する必要があります。最も簡単な方法は、このメソッドを汎用的にすることです。あなたが遭遇する1つの問題は、パブリックなパラメータレスコンストラクタを持っていなければならないということです。

public TOrganism Reproduce<TOrganism>() 
    where TOrganism : Organism, new() 
{ 
    double[] copy = new double[genes.Count]; 
    for(int i = 0; i < copy.Length; i++) 
     // 10% chance to mutate, change up to 10% 
     copy[i] = genes[i] + (Program.rand.Next(10) < 1 ? 
      genes[i] * 0.2 * (Program.rand.NextDouble() - 0.5) : 0.0); 

    TOrganism child = new TOrganism(); 
    child.Genes = genes; 
    return child; 
} 

次に、このメソッドを呼び出します。

Plant myPlant = new Plant(); 
Plant newPlant = myPlant.Reproduce<Plant>(); 

私はさらに一歩進んで、テストを容易にするためにこれを別のクラスにします。たぶん拡張メソッドです。

public static class OrganismReproducer : IOrganismReproducer 
{ 
    public static TOrganism Reproduce<TOrganism>(this TOrganism organism) 
     where TOrganism : Organism, new() 
    { 
     double[] copy = new double[organism.Genes.Count]; 

     for(int i = 0; i < copy.Length; i++) 
      // 10% chance to mutate, change up to 10% 
      copy[i] = genes[i] + (Program.rand.Next(10) < 1 ? 
       genes[i] * 0.2 * (Program.rand.NextDouble() - 0.5) : 0.0); 

     TOrganism child = new TOrganism(); 
     child.Genes = genes; 
     return child; 
    } 
} 

このように呼び出すことができます。

Plant myPlant = new Plant(); 
Plant newPlant = myPlant.Reproduce(); 
    // no need to specify generic type parameter 
    // it is inferred based on the type of myPlant 
+0

ありがとう私は最初のオプションを使用します。 – MrFox

0

ここでオブジェクト指向を見て、デザインする必要があります。このメソッドは、生物または植物がReproduce()をオーバーライドしている間に継承し、その基本型として独自の型のインスタンスを返す基本クラスを返すことができます。あるいは、植物は生物を継承し、この植物のインスタンス化を生物として戻す方法を無効にすることができます。

は(注:私は植物が生物であるかどうかを知りませんので、私は生物学者ではないよ)

1

あなたはリフレクションを使用することができますが、その子クラスのコンストラクタを呼び出す親クラスを持つ魚に見える

public Organism Reproduce() 
{ 
    double[] copy = new double[genes.Count]; 
    for(int i = 0; i < copy.Length; i++) 
     // 10% chance to mutate, change up to 10% 
     copy[i] = genes[i] + (Program.rand.Next(10) < 1 ? 
      genes[i] * 0.2 * (Program.rand.NextDouble() - 0.5) : 0.0); 

    return Activator.CreateInstance(GetType(), copy); 
} 
関連する問題