#1,037 – Specifying Type Parameter Constraints for More than One Type Parameter

If you define a generic type that includes more than one type parameter, you can specify type parameter constraints for each parameter independently.

In the example below, we define a generic class that accepts two type parameters.  We specify that the first type must be one that implements the IMoo interface and that the second type must implement IBark.

    public class MooBarkPile<T1,T2> where T1 : IMoo
                                   where T2 : IBark
    {
        private List<T1> mooPile = new List<T1>();
        private List<T2> barkPile = new List<T2>();

        public void AddMooThing(T1 thing)
        {
            mooPile.Add(thing);
            mooPile[mooPile.Count - 1].Moo();
        }

        public void AddBarkThing(T2 thing)
        {
            barkPile.Add(thing);
            barkPile[barkPile.Count - 1].Bark("Woof");
        }
    }

We can now use the type as follows:

            MooBarkPile<Cow,Dog> aPile = new MooBarkPile<Cow,Dog>();
            aPile.AddBarkThing(new Dog("Kirby", 10));
            aPile.AddMooThing(new Cow("Bessie"));

1037-001

#546 – Specifying More than One Constraint for the Same Type Parameter

You can enforce a constraint on a type parameter for a generic class using the where keyword.  Following the where keyword, you typically indicate a type or interface that the actual parameter must adhere to.

You can define more than one constraint for the same type parameter.

In the example below, the TFavThing parameter must represent a type that implements both the IBuryable and IEdible interfaces.

    public class Dog<TFavThing>
        where TFavThing: IBuryable, IEdible
    {
        public void BuryThing(TFavThing thing)
        {
            thing.Bury();
        }

        public void Eat(TFavThing eatThis)
        {
            eatThis.Eat();
        }
            Dog<Bone> d = new Dog<Bone>("Buster", 5);

            Bone myBone = new Bone("Rawhide");
            d.BuryThing(myBone);
            d.Eat(myBone);