An Introduction to C# Generics[2]

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

本文简介:选择自 13121982 的 blog

public class stringstack
{
string[] m_items;
public void push(string item){...}
public string pop(){...}
}
stringstack stack = new stringstack();
stack.push("1");
string number = stack.pop();
and so on. unfortunately, solving the performance and type-safety problems this way introduces a third,
and just as serious problem—productivity impact. writing type-specific data structures is a tedious,
repetitive, and error-prone task. when fixing a defect in the data structure, you have to fix it not just in
one place, but in as many places as there are type-specific duplicates of what is essentially the same data
structure. in addition, there is no way to foresee the use of unknown or yet-undefined future types, so
you have to keep an object-based data structure as well. as a result, most developers find type-specific
data structures to be impractical and opt for using object-based data structures, in spite of their
deficiencies.
what are generics
generics allow you to define type-safe classes without compromising type safety, performance, or
productivity. you implement the server only once as a generic server, while at the same time you can
declare and use it with any type. to do that, use the < and > brackets, enclosing a generic type
parameter. for example, here is how you define and use a generic stack:
public class stack<t>
{
t[] m_items;
public void push(t item)
{...}
public t pop()
{...}
}
stack<int> stack = new stack<int>();
stack.push(1);
stack.push(2);
int number = stack.pop();
code block 2 shows the full implementation of the generic stack. compare code block 1 to code block
2 and see that it is as if every use of object in code block 1 is replaced with t in code block 2, except
that the stack is defined using the generic type parameter t:
public class stack<t>
{...}
when using a generic stack, you have to instruct the compiler which type to use instead of the generic
type parameter t, both when declaring the variable and when instantiating it:
stack<int> stack = new stack<int>();
the compiler and the runtime do the rest. all the methods (or properties) that accept or return a t will
instead use the specified type, an integer in the example above.
code block 2. the generic stack
public class stack<t>
{
readonly int m_size;
int m_stackpointer = 0;
t[] m_items;
public stack():this(100)
{}
public stack(int size)
{
m_size = size;
m_items = new t[m_size];
}
public void push(t item)
{
if(m_stackpointer >= m_size)
throw new stackoverflowexception();
m_items[m_stackpointer] = item;
m_stackpointer++;
}
public t pop()
{
m_stackpointer--;
if(m_stackpointer >= 0)
{
return m_items[m_stackpointer];
}
else
{
m_stackpointer = 0;
throw new invalidoperationexception("cannot pop an empty
stack");
}
}
}
note t is the generic type parameter (or type parameter) while the generic type is the stack<t>.
the advantage of this programming model is that the internal algorithms and data manipulation remain
the same while the actual data type can change based on the way the client uses your server code.
generics implementation
on the surface c# generics look syntactically similar to c++ templates, but there are important
differences in the way they are implemented and supported by the compiler. as you will see later in this
article, this has significant implications on the manner in which you use generics.
note in the context of this article, when referring to c++ it means classic c++, not microsoft c++ with
the managed extensions.
compared to c++ templates, c# generics can provide enhanced safety but are also somewhat limited in
capabilities.
in some c++ compilers, until you use a template class with a specific type, the compiler does not even
compile the template code. when you do specify a type, the compiler inserts the code inline, replacing
every occurrence of the generic type parameter with the specified type.. in addition, every time you use
a specific type, the compiler inserts the type-specific code, regardless of whether you have already
specified that type for the template class somewhere else in the application. it is up to the c++ linker to
resolve this, and it is not always possible to do. this may results in code bloating, increasing both the load
time and the memory footprint.
in .net 2.0, generics have native support in il (intermediate language) and the clr itself. when you
compile generic c# server-side code, the compiler compiles it into il, just like any other type. however,
the il only contains parameters or place holders for the actual specific types. in addition, the metadata
of the generic server contains generic information.

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

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

go top