A
is inherited by
B
, but not by
C
. Notice also that
A
declares a
method called
Hello( )
. Next, notice that
Test
is a generic class that is declared like this:
class Test where T : A {
The
where
clause stipulates that any type argument specified for
T
must have
A
as a base
class.
Now notice that
Test
declares the method
SayHello( )
, shown next:
public void SayHello() {
// OK to call Hello() because it’s declared
// by the base class A.
obj.Hello();
}
This method calls
Hello( )
on
obj
, which is a
T
object. The key point is that the only reason
that
Hello( )
can be called is because the base class constraint requires that any type argument
bound to
T
must be
A
or inherit
A
, and
A
declares
Hello( )
. Thus, any valid
T
will define
Hello( )
. If the base class constraint had not been used, the compiler would have no way of
knowing that a method called
Hello( )
could be called on a object of type
T
. You can prove
this for yourself by removing the
where
clause. The program will no longer compile because
the
Hello( )
method will be unknown.
In addition to enabling access to members of the base class, the base class constraint
enforces that only types that inherit the base class can be passed as type arguments. This
is why the following two lines are commented-out:
// Test t3 = new Test(c); // Error!
// t3.SayHello(); // Error!
Because
C
does not inherit
A
, it can’t be used as a type argument when constructing a
Test
object. You can prove this by removing the comment symbols and trying to recompile.
Before continuing, let’s review the two effects of a base class constraint: A base class
constraint enables a generic class to access the members of the base class. It also ensures that
only those type arguments that fulfill this constraint are valid, thus preserving type safety.
Although the preceding example shows the “how” of base class constraints, it does not
show the “why.” To better understand the value of base type constraints, let’s work through
another, more practical example. Assume you want to create a mechanism that manages
lists of telephone numbers. Furthermore, assume you want to use different lists for different
groupings of numbers. Specifically, you want one list for friends, another for suppliers, and
so on. To accomplish this, you might start by creating a base class called
PhoneNumber
that
stores a name and a phone number linked to that name. Such a class might look like this:
www.freepdf-books.com
Do'stlaringiz bilan baham: |