开发者

Need to abstract collections of objects (C#)

开发者 https://www.devze.com 2023-01-31 07:58 出处:网络
In the following simplified example, I need to abstract Collection classes in such a way that PrintFruitsAndEaters(oranges, orangeEaters); or PrintFruitsAndEaters(apples, appleEaters);

In the following simplified example, I need to abstract Collection classes in such a way that PrintFruitsAndEaters(oranges, orangeEaters); or PrintFruitsAndEaters(apples, appleEaters); becomes possible:

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<Oran开发者_运维知识库geEater>

I've tried templatizing the method and collection classes, but i need to access methods specific to Fruit and FruitEater classes:

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

void PrintFruitsAndEaters<T, S>(FruitCollection<T> fruits, FruitEaterCollection<S> eaters)


Then you want this:

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

This will constrain the T and S types as you require; calling the method with a FruitCollection<T>, where the T cannot be guaranteed to be Fruit or a subtype, will result in a compile-time error. Same with S and FruitEater.

Because of the constraint, when working with a value of type T you will be able to access members of the Fruit class, and when working with a value of type S you will be able to access members of the FruitEater class.

Note that, as per Brian's (deleted) answer, you might want to add constraints to the collection types too:

class FruitCollection<T> : List<T> where T : Fruit { }
class FruitEaterCollection<T> : List<T> where T : FruitEater { }

But this will still not allow you to omit the constraints on the method.

(Also, inheriting List<T> is an evil thing to do, instead use IList<T>)

0

精彩评论

暂无评论...
验证码 换一张
取 消