An Introduction to C# Generics[4]

[入库:2005年8月18日] [更新:2007年3月25日]

本文简介:选择自 13121982 的 blog

constructed with integers, the pop() methods return zero when the stack is empty.
multiple generic types
a single type can define multiple generic types parameters. for example, consider the generic linked list
shown in code block 3.
code block 3. generic linked list
class node<k,t>
{
public node()
{
key = k.default;
item = t.default;
nextnode = null;
}
public node(k key,t item,node<k,t> nextnode)
{
key = key;
item = item;
nextnode = nextnode;
}
public k key;
public t item;
public node<k,t> nextnode;
}
public class linkedlist<k,t>
{
public linkedlist()
{
m_head = new node<k,t>();
}
public void addhead(k key,t item)
{
node<k,t> newnode = new node<k,t>(key,item,m_head.nextnode);
m_head.nextnode = newnode;
}
node<k,t> m_head;
}
the linked list stores nodes:
class node<k,t>
{...}
each node contains a key (of the generic type parameter k) and a value (of the generic type parameter
t). each node also has a reference to the next node in the list. the linked list itself is defined in terms of
the generic type parameters k and t:
public class linkedlist<k,t>
{...}
this allows the list to expose generic methods like addhead():
public void addhead(k key,t item);
whenever you declare a variable of a type that uses generics, you must specify the types to use. however,
the specified types can themselves be generic types. for example, the linked list has a member variable
called m_head of type node, used for referencing the first item in the list. m_head is declared using the
list's own generic type parameters k and t
node<k,t> m_head;
you need to provide specific types when instantiating a node, and again, you can use the linked list's own
generic type parameters:
public void addhead(k key,t item)
{
node<k,t> newnode = new node<k,t>(key,item,m_head.nextnode);
m_head.nextnode = newnode;
}
note that the fact the list uses the same names as the node for the generic type parameters is purely for
readability purposes, and it could have used other names, such as:
public class linkedlist<u,v>
{...}
or:
public class linkedlist<keytype,datatype>
{...}
in which case, m_head would have been declared as:
node<keytype,datatype> m_head;
when the client is using the linked list, the client has to provide specific types. the client can choose
integers as keys and strings as data items:
linkedlist<int,string> list = new linkedlist<int,string>();
list.addhead(123,"aaa");
but the client can choose any other combination, such as a time stamp for keys:
linkedlist<datetime,string> list = new linkedlist<datetime,string>();
list.addhead(datetime.now,"aaa");
sometimes is it useful to alias a particular combination of specific types. you can do that through the
using statement, as shown in code block 4. note that the scope of aliasing is the scope of the file, so you
have to repeat aliasing across the project files in the same way you would with using namespaces.
code block 4. generic type aliasing
using list = linkedlist<int,string>;
class listclient
{
static void main(string[] args)
{
list list = new list();
list.addhead(123,"aaa");
}
}
generic constraints
with c# generics, the compiler compiles the generic code into il independent of any specific types that
the clients will use. as a result, the generic code could try to use methods, properties, or members of the
generic type parameters that are incompatible with the specific types the client uses. this is
unacceptable because it amounts to lack of type safety. in c# you need to instruct the compiler which
constraints the client-specified types must obey in order for them to be used instead of the generic type
parameters. there are two types of constraints. a derivation constraint indicates to the compiler that the
generic type parameter derives from a base type such an interface or a particular base class. a default
constructor constraint indicates to the compiler that the generic type parameter exposes a default public
constructor (a public constructor with no parameters). a generic type can employ multiple constraints,
and you even get intellisense reflecting the constraints when using the generic type parameter, such as
suggesting methods or members from the base type.
it is important to note that although constraints are optional, they are often essential when developing
a generic type. without them, the compiler takes the more conservative, type-safe approach and only
allows access to object-level functionality in your generic type parameters. constraints are part of the

本文关键:An Introduction to C# Generics
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top