只允许将特定对象类型传递到基于派生类类型的方法中

本文关键字:类型 于派生 派生 方法 对象 | 更新日期: 2023-09-27 18:08:46

我有一个基类,它有一个名为AddFruit的方法,该方法采用Fruit类型的类并以一般方式处理它。

    public abstract class Foo
    {
        protected List<ProcessedFruit> processedFruit = new List<ProcessedFruit>();
        public void AddFruit(Fruit o)       
        {
            // Process fruit
            processedFruit.Add(o);
        }
        public void Update()
        {
            // Do base class specific stuff here
            OnUpdate();
        }
        protected abstract void OnUpdate();
    }
    public class AppleBar : Foo
    {
        public AppleBar()
            :base(){}
        protected override void OnUpdate() { }
    }
    public class BananaBar : Foo
    {
        public BananaBar()
            :base(){}
        protected override void OnUpdate() { }
    }

Foo派生的任何类都以非一般方式更新,并且将以不同的方式使用ProcessedFruit列表。

Fruit可以在Bar类实例化后的任何时间被添加和处理。

    public abstract class Fruit
    {
    }
    public class Banana : Fruit
    {
    }
    public class Apple : Fruit
    {
    }

我想知道,是否有可能只允许基于派生的Bar类类型添加特定类型的Fruit类?

例如:

  • AppleBar只允许添加类型Apple
  • BananaBar只允许添加类型Banana

我明白我可以覆盖AddFruit方法,但我希望处理保持在基类中,并希望避免在与BananaBarAppleBar派生类相关的覆盖方法中调用base.AddFruit

我也希望避免使用GetType()检查Fruit的类型。

理想情况下,我想要的东西如下:

var o = new AppleBar()
// This has to be an Apple and intellisense can recognise this 
o.AddFruit(...);          

这可能吗?

编辑:

我在使用以下泛型时遇到问题:

 List<Foo<Fruit>> commands = new List<Foo<Fruit>>(10);
 commands.Add(new AppleBar());    // Can't be added
 commands.Add(new BananaBar());   // Can't be added

只允许将特定对象类型传递到基于派生类类型的方法中

最简单的方法是在基类上使用泛型类型参数,然后由继承类用特定类型填充该参数:

public abstract class Foo<T> where T : Fruit
{
    protected List<ProcessedFruit> processedFruit = new List<ProcessedFruit>();
    public void AddFruit(T o)       
    {
        // Process fruit
        processedFruit.Add(o);
    }
    public void Update()
    {
        // Do base class specific stuff here
        OnUpdate();
    }
    protected abstract void OnUpdate();
}
public class AppleBar : Foo<Apple>
{
    //...
}

为什么不能将AppleBar添加到List<Foo<Fruit>>中?