C# 用作抽象方法的基类';s参数?

C# 用作抽象方法的基类';s参数?,c#,overriding,abstract-class,abstract,C#,Overriding,Abstract Class,Abstract,我正在尝试设置一些类,如: public abstract class AnimalBase { public string SpeciesName { get; private set; } public AnimalBase(string speciesName) { this.SpeciesName = speciesName; } public abstract void CopyFrom(AnimalDefaultClass defaultVal

我正在尝试设置一些类,如:

public abstract class AnimalBase {      
  public string SpeciesName { get; private set; }

  public AnimalBase(string speciesName) {
    this.SpeciesName = speciesName;
  }

  public abstract void CopyFrom(AnimalDefaultClass defaultVals);
}

public class Mammal : AnimalBase {
  public bool WalksUpright { get; private set; }

  public Mammal(string speciesName) : base(speciesName) {
    this.CopyFrom(new MammalDefaultClass(speciesName));
  }

  public override void CopyFrom(MammalDefaultClass defaultVals) {
    this.WalksUpright = defaultVals.WalksUpright;
  }

  public void Cripple() {
    this.WalksUpright = false;
  }
}

public class MammalDefaultClass : AnimalDefaultClass {
  public bool WalksUpright { get; private set; }

  public MammalDefaultClass(string speciesName) {
    using (var dataStore = theoreticalFactory.GetDataStore()) {
      this.WalksUpright = dataStore[speciesName].WalksUpright;
    }
  } 
}
显然,这并不是我想要实现的目标,但我的想法是:

  • 从抽象基础(动物)继承的几个类别(哺乳动物、鱼、昆虫等)
  • 每个子类都有一个对应的类,它可以使用(在本例中填充可变的默认值)作为基类中定义为抽象的方法的参数
  • 每个相应的类(MailomaDefaultClass、FishDefaultClass、InsectDefaultClass等)都从公共基类(AnimalDefaultClass)继承
这些AnimalDefaultClass衍生物的存在是因为每一类动物都有不同的属性,但根据定义,总会有一个类能够为任何动物获取这些值

我的问题是:

被重写的CopyFrom版本(EmilamaDefaultClass)未被识别为抽象CopyFrom(AnimalDefaultClass)的有效重写,即使EmilamaDefaultClass继承自AnimalDefaultClass

是否可以将基类指定为抽象成员的参数?有简单的解决办法吗?还是这整件事都搞错了

-编辑:我的分辨率- 在考虑了MWB和sza的一些建议后,我最终让每个子类使用base参数实现该方法,然后根据需要转换输入,如:

public class Mammal : AnimalBase {
  ...

  // implements the abstract method from the base class:
  public override void CopyFrom(AnimalDefaultClass defaultVals) {
    this.CopyFrom((MammalDefaultClass)defaultVals);
  }

  public void CopyFrom(MammalDefaultClass defaultVals) {
    this.WalksUpright = defaultVals.WalksUpright;
  }
}

这个解决方案迫使我始终实现一个CopyFrom(AnimalDefaultClass),这就是将抽象方法放在基类中的首要目的

因此,事实证明,即使MailamDefaultClass是AnimalDefaultClass的子类,也不能用一个函数重写一个接受AnimalDefaultClass的函数

考虑这段代码:

public class Dinosaur : AnimalDefaultClass;
Dinosaur defaultDinosaur;

public void makeDinosaur(AnimalDefaultClass adc)
{
    adc.CopyFrom(defaultDinosaur);
}

MammalDefaultClass m;
makeDinosaur(m);
在本例中,MadameDefaultClass是AnimalDefaultClass的一个子类,因此可以将m作为adc传递给MakeDiology。此外,AnimalDefault类的CopyFrom只需要另一个AnimalDefault类,因此我可以传入恐龙。但这个类实际上是哺乳动物,所以需要一个哺乳动物类,而恐龙不是


解决方法是采用原始类型签名,如果参数的类型错误(类似于Java中数组的行为),则抛出错误。

我认为您可以尝试抽象工厂模式。基本上,您希望在创建对象的过程中处理一些构造逻辑,对于产品的每个不同子类型,您可以执行不同的操作

public abstract class AnimalBase
{
    public string SpeciesName { get; private set; }

    protected AnimalBase(string speciesName)
    {
        this.SpeciesName = speciesName;
    }
}

public class Mammal : AnimalBase
{
    public bool WalksUpright { get; set; }

    public Mammal(string speciesName) : base(speciesName)
    {
    }

    public void Cripple()
    {
        this.WalksUpright = false;
    }
}

public interface IAnimalFactory<T> where T : AnimalBase
{
    T CreateAnAnimal(string speciesName);
}

public class MammalFactory: IAnimalFactory<Mammal>
{
    public Mammal CreateAnAnimal(string speciesName)
    {
        var mammal = new Mammal(speciesName);
        var mammalDefault = new MammalDefaultClass(speciesName);
        mammal.WalksUpright = mammalDefault.WalksUpright;
        return mammal;
    }
}

看起来不错。您可以考虑仅将<代码> MammalDefaultClass <代码>本身作为工厂并将属性直接存储在<代码>哺乳动物< /代码>中,这样您就不必复制<代码> WalksUpright <代码>属性。例如,
var哺乳动物=新的哺乳动物默认类(speciesName).CreateDefault()
。此外,考虑模板化类以避免抛出:<代码> iMnFieldFrand,其中T:AnimalBase < /代码>。谢谢建议和示例。我玩了一些,这似乎不是一个很好的适合我的情况下(可能已经在我的问题误导,如果是这样的话,对不起)。我正在用我最终使用的解决方案更新我的问题。我最终使用了您的解决方案。在本例中,我将用一些细节更新我的问题,以便使用代码格式。
var mammalFactory = new MammalFactory();
var bunny = mammalFactory.CreateAnAnimal("Bunny");