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

use*_*893 2 c# derived-class

我有一个基类,它有一个方法调用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() { }
    }
Run Code Online (Sandbox Code Playgroud)

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

Fruit可以Bar在实例化类之后的任何时候添加和处理.

    public abstract class Fruit
    {

    }

    public class Banana : Fruit
    {

    }

    public class Apple : Fruit
    {

    }
Run Code Online (Sandbox Code Playgroud)

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

例如:

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

我知道我可以覆盖该AddFruit方法,但我希望处理保留在基类中,并希望避免调用与派生类base.AddFruit相关的重写方法.BananaBarAppleBar

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

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

var o = new AppleBar()

// This has to be an Apple and intellisense can recognise this 
o.AddFruit(...);          
Run Code Online (Sandbox Code Playgroud)

这可能吗?

编辑:

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

 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
Run Code Online (Sandbox Code Playgroud)

Ben*_*son 6

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

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>
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

更新

请参阅此答案,了解无法添加AppleBar到a 的原因的说明List<Foo<Fruit>>