需要抽象对象集合(C#)

kat*_*roh 1 c# oop polymorphism

在下面的简化示例中,我需要在这样的方式的抽象集合类PrintFruitsAndEaters(oranges, orangeEaters);PrintFruitsAndEaters(apples, appleEaters); 成为可能:

abstract class Fruit
abstract class FruitEater

class Apple : Fruit
class AppleEater : FruitEater
class Orange : Fruit
class OrangeEater : FruitEater

class AppleCollection : List<Apple>
class OrangeCollection : List<Orange>
class AppleEaterCollection : List<AppleEater>
class OrangeEaterCollection : List<OrangeEater>
Run Code Online (Sandbox Code Playgroud)

我已经尝试过模板化方法和集合类,但我需要访问特定于Fruit和FruitEater类的方法:

class FruitCollection<T> : List<T>
class FruitEaterCollection<T> : List<T>

void PrintFruitsAndEaters<T, S>(FruitCollection<T> fruits, FruitEaterCollection<S> eaters)
Run Code Online (Sandbox Code Playgroud)

cdh*_*wie 6

那你想要这个:

void PrintFruitsAndEaters<T, S>(
    FruitCollection<T> fruits,
    FruitEaterCollection<S> eaters)
        where T : Fruit
        where S : FruitEater
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这将根据您的需要约束TS类型; 使用a调用方法FruitCollection<T>,其中T无法保证Fruit或子类型,将导致编译时错误.与S和相同FruitEater.

由于约束,当使用类型值时,T您将能够访问Fruit类的成员,并且当使用类型值时,S您将能够访问FruitEater类的成员.

请注意,根据Brian的(已删除)答案,您可能还想为集合类型添加约束:

class FruitCollection<T> : List<T> where T : Fruit { }
class FruitEaterCollection<T> : List<T> where T : FruitEater { }
Run Code Online (Sandbox Code Playgroud)

但是这仍然不允许您省略该方法的约束.

(另外,继承List<T>是一件坏事,而是使用IList<T>)