Inheritance

Generic types can be inherited, but some basic rules apply. For example, the derived class cannot be a closed constructed type. Table 7-1 lists all the possible permutations.

Table 7-1. Inheritance table for generic types

Base class

Derived class

Comments

Generic (open)

Generic (open)

Permitted when the derived class uses the type parameters of the base class

Generic (open)

Generic (closed)

Not permitted

Generic (open)

Non-generic

Permitted

Generic (closed)

Generic (open)

Permitted

Generic (closed)

Generic (closed)

Not permitted

Generic (closed)

Non-generic

Not permitted

Non-generic

Generic (closed)

Permitted

Non-generic

Generic (open)

Not permitted

This sample code shows some of the combinations that are permitted and not permitted:

public class ZClass<T> {
}

public class XClass<T> : ZClass<T> {
}

public class BClass<Y> {
}

public class AClass<Z> : BClass<int> {
}

public class YClass : ZClass<int> {
}

/*
public class AClass<Z> : BClass<Y> {    // illegal
}

public class YClass : ZClass<T> {       // illegal
}
*/

When inheriting an open constructed type, the constraints of the base class must be repeated in the derived type. The derived type also can add additional type parameters. This is not applicable to closed constructed types because closed constructed types do not have type parameters or constraints.

Here is sample code combining inheritance of generic types and constraints:

public class ZClass<T> where T : IComparable {
}

public class YClass<T> : ZClass<T> where T : IComparable {
}

public class XClass<T> : ZClass<T> where T : IComparable, IDisposable {
}

public class BClass<Y> where Y : IEnumerable<int> {
}

public class AClass<Z> : BClass<int[]> where Z :IDisposable {
}

Overriding Generic Methods

Methods that have type parameters can be overridden. Conversely, generic methods also can override other methods. Table 7-2 lists the various combinations of overriding generic and non-generic methods. If a base class is non-generic or closed, overriding methods cannot have type parameters. If the base class is open, the overriding method can have type parameters.

Table 7-2. Combination of overriding generic methods

Base method

Derived method

Comments

Non-generic

Generic (open)

Permitted

Non-generic

Generic (closed)

Permitted

Generic (open)

Non-generic

Not permitted

Generic (open)

Generic (open)

Permitted; must use the same type parameters

Generic (open)

Generic (closed)

Not permitted

Generic (closed)

Non-generic

Permitted

Generic (closed)

Generic (closed)

Permitted

Generic (closed)

Generic (open)

Not permitted

Here is example code of overriding a generic method:

using System;

namespace Donis.CSharpBook {

    public class Starter {
        public static void Main() {
        }
    }

    public class ZClass<T> {
        public virtual void MethodA(T arg) {
        }
    }

    public class YClass<T> : ZClass<T>{
        public override void MethodA(T arg) {
        }

//      public override void MethodA(int arg) { // illegal
//      }
    }

    public class XClass<X> : ZClass<int>{
        public override void MethodA(int arg) {
        }

//      public override void MethodA(X arg) { // illegal
//      }
    }

    public class WClass : ZClass<int> {
        public override void MethodA(int arg) {
        }
    }
}

When a generic method overrides another generic method, it inherits the constraints of that method. The overriding method cannot change the constraints inherited from the base method.

The following code correctly overrides a generic method:

public class ZClass {
    public virtual void MethodA<T>(T arg)
        where T : new() {
    }
}

public class YClass : ZClass {
    public override void MethodA<T>(T arg) {
        T obj = new T();
    }
}

Nested Types

You can nest a generic type inside a non-generic type, and vice versa. This is straightforward. More intriguing is nesting generic types inside other generic types. The nested generic type can use the type parameters of the outer type. However, the type parameter of the outer type cannot be redefined as a new type parameter in the nested type. The nested generic type also can declare entirely new type parameters.

This is sample code of nested generic types:

using System;

namespace Donis.CSharpBook {
    public class Starter {
        public static void Main() {
            ZClass<int>.Nested<double> obj =
                new ZClass<int>.Nested<double>();
            obj.MethodA(10, 12.34);
        }
    }

    public class ZClass<T> {
        public void MethodA(T arg) {

        }

        public class Nested<S> {
            public void MethodA(T arg1, S arg2) {
                Console.WriteLine("arg1: {0}",
                    arg1.GetType().ToString());
                Console.WriteLine("arg2: {0}",
                    arg2.GetType().ToString());
            }
        }
    }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.17.27