C# Language: generics, open/closed, bound/unbound, constructed
I'm reading book "the C# programming Language", 4th Edition, by Anders Hejlsberg etc.
There are several definitions that are a bit twisting:
unbound generic type: A generic type declaration, by itself, denotes an unbound generic type ...
constructed type: A type that includes at least one type argument is called a constructed type.
open type: An open type is a type that involves type parameters.
closed type: A closed type is a type that is not an open type.
unbound type: refers to a nongeneric type or an unbound generic type.
bound type: refers to a nongeneric type or a constructed type. [annotate] ERIC LIPPERT: Yes, nongeneric types are considered to be both bound and unbound.
Question 1, is below what I listed correct?
int //non-generic, closed, unbound & bound,
class A<T, U, V> //generic, open, unbound,
class A<int, U, V> //generic, open, bound, constructed
class A<int, int, V> //generic, open, bound, constructed
class A<int, int, int> //generic, closed, bound, constructed
Question 2, The books says "An unbound type refers to the entity declared by a type declaration. An unbound generic type is not itself a type, and it cannot be used as the type of a variable, argument, or return value, or as a base type. The only construct in which an unbound generic type can be referenced is the typeof expression (§7.6.11)." Fine, but below is a small testing program that can compile:
public class A<W, X> { }
// Q2.1: how come unbounded g开发者_如何学Pythoneneric type A<W,X> can be used as a base type?
public class B<W, X> : A<W, X> { }
public class C<T,U,V>
{
// Q2.2: how come unbounded generic type Dictionary<T, U> can be used as a return value?
public Dictionary<T,U> ReturnDictionary() { return new Dictionary<T, U>(); }
// Q2.3: how come unbounded generic type A<T, U> can be used as a return value?
public A<T, U> ReturnB() { return new A<T, U>(); }
}
These are examples of unbound generic types:
List<>
Dictionary<,>
They can be used with typeof
, i.e., the following are valid expressions:
typeof(List<>)
typeof(Dictionary<,>)
That should answer your question 2. With respect to question 1, note that type arguments can be constructed types or type parameters. Thus, your list should be updated as follows:
public class MyClass<T, U> { // declares the type parameters T and U
// all of these are
// - generic,
// - constructed (since two type arguments are supplied), and
// - bound (since they are constructed):
private Dictionary<T, U> var1; // open (since T and U are type parameters)
private Dictionary<T, int> var2; // open (since T is a type parameter)
private Dictionary<int, int> var3; // closed
}
An excellent answer is given by Jon, here.
Not giving a technical description since everything is there perfectly in the linked answer. To merely replicate the gist of it as an answer here, it would look like:
A //non generic, bound
A<U, V> //generic, bound, open, constructed
A<int, V> //generic, bound, open, constructed
A<int, int> //generic, bound, closed, constructed
A<,> (used like typeof(A<,>)) //generic, unbound
Edited after discussion with Heinzi.
精彩评论