2012-02-08 73 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

您将需要使用泛型。最简单的方法是使这种方法通用。你会遇到的一个问题是你必须有一个公共无参数的构造函数。

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 2012-02-11 12:48:33

0

你需要看看OO设计在这里。该方法可以返回生物体或植物都从其继承的基类,同时覆盖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); 
} 
相关问题