如何使返回类型为current类,子类将使用该方法

时间:2012-02-08 16:03:35

标签: c#

我正在模拟一个生态系统,它非常简单,所以不要担心现实主义。 复制方法位于Organism类中,它可以完全由类Plant使用,除了返回类型是Organism:

    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中可以返回'self',所以如果扩展了这个方法的类使用了该方法,该方法将返回继承类的对象。

所以问题是:我如何修改这个方法,这样当它从一个工厂调用时,它会生成一个工厂并返回一个工厂?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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);
}

答案 2 :(得分:0)

你需要在这里看一下OO和设计。该方法可以返回生物体或植物都继承的基类,同时重写Reproduce()并返回它们自己类型的实例化作为基类型。或者植物可以从生物体中继承并覆盖该方法以返回植物作为生物体的实例化。

(注意:我不是生物学家所以我不知道植物是否是有机体。)