534
Part I: The C# Language
Creating a Default Value of a Type Parameter
When writing generic code, there will be times when the difference between value types 
and refer
of a type parameter a default value. For reference types, the default value is null. For non-
struct value types, the default value is 0, or false for bool. The default value for a struct is 
an object of that struct with all fields set to their defaults. Thus, trouble occurs if you want 
null, 0, 
false, or something else?
For example, given a generic class called Test declared like this:
class Test<T> {
T obj;
// ...
if you want to give obj a default value, neither
obj = null; // works only for reference types
nor
obj = 0; // works only for numeric types and enums
works in all classes.
The solution to this problem is to use another form of default, shown here:
default(type)
This is the operator form of default, and it produces a default value of the specified type,no
matter what type is used. Thus, continuing with the example, to assign obj a default value 
of type T, you would use this statement:
obj = default(T);
This will work for all type arguments, whether they are value or reference types.
Here is a short program that demonstrates default:
// Demonstrate the default operator.
using System;
class MyClass {
//...
}
// Construct a default value of T.
class Test<T> {
public T obj;
public Test() {
// The following statement would work only for reference types.
//    obj = null; // can’t use
// The following statement will work only for numeric value types.
//    obj = 0; // can’t use
Pdf split and merge - Merge, append PDF files in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Provide C# Demo Codes for Merging and Appending PDF Document
combine pdf; add two pdf files together
Pdf split and merge - VB.NET PDF File Merge Library: Merge, append PDF files in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
VB.NET Guide and Sample Codes to Merge PDF Documents in .NET Project
append pdf files reader; adding pdf pages together
P
A
R
T
I
Chapter 18: Generics 
535
P
A
R
T
I
P
A
R
T
I
// This statement works for both reference and value types.
obj = default(T); // Works!
}
// ...
}
class DefaultDemo {
static void Main() {
// Construct Test using a reference type.
Test<MyClass> x = new Test<MyClass>();
if(x.obj == null)
Console.WriteLine("x.obj is null.");
// Construct Test using a value type.
Test<int> y = new Test<int>();
if(y.obj == 0)
Console.WriteLine("y.obj is 0.");
}
}
The output is shown here:
x.obj is null.
y.obj is 0.
Generic Structures
C# allows you to create generic structures. The syntax is the same as for generic classes. For 
example, in the following program, the XY structure, which stores X, Y coordinates, is generic:
// Demonstrate a generic struct.
using System;
// This structure is generic.
struct XY<T> {
T x;
T y;
public XY(T a, T b) {
x = a;
y = b;
}
public T X {
get { return x; }
set { x = value; }
}
public T Y {
get { return y; }
C# PDF File Split Library: Split, seperate PDF into multiple files
PDF ›› C# PDF: Split PDF. C# PDF - Split PDF Document in C#.NET. Explain How to Split PDF Document in Visual C#.NET Application. C# DLLs: Split PDF Document.
reader create pdf multiple files; acrobat combine pdf
VB.NET PDF File Split Library: Split, seperate PDF into multiple
File: Split PDF Document. |. Home ›› XDoc.PDF ›› VB.NET PDF: Split PDF. VB.NET PDF - Split PDF Document Using VB.NET. VB.NET
attach pdf to mail merge; c# merge pdf
536
Part I: The C# Language
set { y = value; }
}
}
class StructTest {
static void Main() {
XY<int> xy = new XY<int>(10, 20);
XY<double> xy2 = new XY<double>(88.0, 99.0);
Console.WriteLine(xy.X + ", " + xy.Y);
Console.WriteLine(xy2.X + ", " + xy2.Y);
}
}
The output is shown here:
10, 20
88, 99
Like generic classes, generic structures can have constraints. For example, this version of 
XY restricts type arguments to value types:
struct XY<T> where T : struct {
// ...
Creating a Generic Method
As the pr
class’ type parameter and are, therefore, automatically generic relative to the type parameter. 
However, it is possible to declare a generic method that uses one or more type parameters 
of its own. Furthermore, it is possible to create a generic method that is enclosed within a 
non-generic class.
Let’s begin with an example. The following program declares a non-generic class called 
ArrayUtils and a static generic method within that class called CopyInsert( ). The CopyInsert( )
method copies the contents of one array to another, inserting a new element at a specified 
location in the process. It can be used with any type of array.
// Demonstrate a generic method.
using System;
// A class of array utilities. Notice that this is not
// a generic class.
class ArrayUtils {
// Copy an array, inserting a new element
// in the process. This is a generic method.
public static bool CopyInsert<T>(T e, uint idx,
T[] src, T[] target) {
// See if target array is big enough.
if(target.Length < src.Length+1)
return false;
C# PDF: C#.NET PDF Document Merging & Splitting Control SDK
C# PDF - Merge or Split PDF File in C#.NET. C#.NET Code Demos to Combine or Divide Source PDF Document File. Visual C#. VB.NET. Home
scan multiple pages into one pdf; pdf mail merge
VB.NET PDF: Use VB.NET Code to Merge and Split PDF Documents
VB.NET PDF - How to Merge and Split PDF. How to Merge and Split PDF Documents by Using VB.NET Code. Visual C#. VB.NET. Home > .NET Imaging
build pdf from multiple files; add pdf files together online
P
A
R
T
I
Chapter 18: Generics 
537
P
A
R
T
I
P
A
R
T
I
// Copy src to target, inserting e at idx in the process.
for(int i=0, j=0; i < src.Length; i++, j++) {
if(i == idx) {
target[j] = e;
j++;
}
target[j] = src[i];
}
return true;
}
}
class GenMethDemo {
static void Main() {
int[] nums = { 1, 2, 3 };
int[] nums2 = new int[4];
// Display contents of nums.
Console.Write("Contents of nums: ");
foreach(int x in nums)
Console.Write(x + " ");
Console.WriteLine();
// Operate on an int array.
ArrayUtils.CopyInsert(99, 2, nums, nums2);
// Display contents of nums2.
Console.Write("Contents of nums2: ");
foreach(int x in nums2)
Console.Write(x + " ");
Console.WriteLine();
// Now, use copyInsert on an array of strings.
string[] strs = { "Generics", "are", "powerful."};
string[] strs2 = new string[4];
// Display contents of strs.
Console.Write("Contents of strs: ");
foreach(string s in strs)
Console.Write(s + " ");
Console.WriteLine();
// Insert into a string array.
ArrayUtils.CopyInsert("in C#", 1, strs, strs2);
// Display contents of strs2.
Console.Write("Contents of strs2: ");
foreach(string s in strs2)
Console.Write(s + " ");
VB.NET TIFF: Merge and Split TIFF Documents with RasterEdge .NET
Merge certain pages from different TIFF documents and create a &ltsummary> ''' Split a TIFF provide powerful & profession imaging controls, PDF document, tiff
acrobat merge pdf; merge pdf online
VB.NET PDF Library SDK to view, edit, convert, process PDF file
Tell VB.NET users how to: create a new PDF file and load PDF from other file formats; merge, append, and split PDF files; insert, delete, move, rotate, copy
append pdf; best pdf merger
538
Part I: The C# Language
Console.WriteLine();
// This call is invalid because the first argument
// is of type double, and the third and fourth arguments
// have element types of int.
//    ArrayUtils.CopyInsert(0.01, 2, nums, nums2);
}
}
The output from the program is shown here:
Contents of nums: 1 2 3
Contents of nums2: 1 2 99 3
Contents of strs: Generics are powerful.
Contents of strs2: Generics in C# are powerful.
Let’s examine CopyInsert( ) closely. First, notice how it is declared by this line:
public static bool CopyInsert<T>(T e, uint idx,
T[] src, T[] target) {
The type parameter is declared after the method name, but before the parameter list. Also 
notice that CopyInsert( ) is static, enabling it to be called independently of any object. 
e is no 
restriction in this regard.
Now, notice how CopyInsert( ) is called within Main( ) by use of the normal call syntax, 
without the need to specify type arguments. This is because the types of the arguments are 
automatically discerned, and the type of T is adjusted accordingly. This process is called 
typeinference. For example, in the first call:
ArrayUtils.CopyInsert(99, 2, nums, nums2);
the type of T becomes int because 99 and the element types of nums and nums2 are int. In 
the second call, string types are used, and T is replaced by string.
Now, notice the commented-out code, shown here:
//    ArrayUtils.CopyInsert(0.01, 2, nums, nums2);
If you remove the comments and then try to compile the program, you will receive an error. 
The reason is that the type of the first argument is double, but the element types of nums
andnums2 are int. However, all three types must be substituted for the same type 
parameter, T. This causes a type-mismatch, which results in a compile-time error. This 
ability to enfor
The syntax used to create CopyInsert( ) can be generalized. Here is the general form of 
a generic method:
ret-typemeth-name<type-param-list>(param-list) { // ...
In all cases, type-param-listis a comma-separated list of type parameters. Notice that for a 
generic method, the type parameter list follows the method name.
C# PDF File & Page Process Library SDK for C#.net, ASP.NET, MVC
functions. Able to create, load, merge, and split PDF document using C#.NET code, without depending on any product from Adobe. Compatible
acrobat combine pdf files; split pdf into multiple files
C# PDF Page Insert Library: insert pages into PDF file in C#.net
for each of those page processing functions, such as how to merge PDF document files NET, how to reorganize PDF document pages and how to split PDF document in
add multiple pdf files into one online; combine pdf online
P
A
R
T
I
Chapter 18: Generics 
539
P
A
R
T
I
P
A
R
T
I
Using Explicit Type Arguments to Call a Generic Method
Although implicit type inference is adequate for most invocations of a generic method, it is 
possible to explicitly specify the type argument. To do so, specify the type argument after 
the method name when calling the method. For example, here CopyInsert( ) is explicitly 
passed type string:
ArrayUtils.CopyInsert<string>("in C#", 1, strs, strs2);
Y
T parameter or if you want to override the type inference.
Using a Constraint with a Generic Method
You can add constraints to the type arguments of a generic method by specifying them after 
the parameter list. For example, the following version of CopyInsert( ) will work only with 
reference types:
public static bool CopyInsert<T>(T e, uint idx,
T[] src, T[] target) where T : class {
If you were to try this version in the program shown earlier, then the following call to 
CopyInsert( ) would not compile because int is a value type, not a reference type:
// Now wrong because T must be reference type!
ArrayUtils.CopyInsert(99, 2, nums, nums2); // Now illegal!
Generic Delegates
Like methods, delegates can also be generic. To declare a generic delegate, use this general 
form:
delegateret-typedelegate-name<type-parameter-list>(arg-list);
, a 
generalized form that can then be matched to any compatible method.
The following program demonstrates a generic delegate called SomeOpthat has one 
type parameter called T. It returns type T and takes an argument of type T.
// A simple generic delegate.
using System;
// Declare a generic delegate.
delegate T SomeOp<T>(T v);
class GenDelegateDemo {
// Return the summation of the argument.
static int Sum(int v) {
int result = 0;
for(int i=v; i>0; i--)
540
Part I: The C# Language
result += i;
return result;
}
// Return a string containing the reverse of the argument.
static string Reflect(string str) {
string result = "";
foreach(char ch in str)
result = ch + result;
return result;
}
static void Main() {
// Construct an int delegate.
SomeOp<int> intDel = Sum;
Console.WriteLine(intDel(3));
// Construct a string delegate.
SomeOp<string> strDel = Reflect;
Console.WriteLine(strDel("Hello"));
}
}
The output is shown here:
6
olleH
Let’s look closely at this program. First, notice how the SomeOp delegate is declared:
delegate T SomeOp<T>(T v);
Notice that T can be used as the return type even though the type parameter T is specified 
after the name SomeOp.
InsideGenDelegateDemo, the methods Sum( ) and Reflect( ) are declared, as shown 
here:
static int Sum(int v) {
static string Reflect(string str) {
TheSum( ) method returns the summation of the integer value passed as an argument. The 
Reflect( ) method returns a string that is the reverse of the string passed as an argument.
InsideMain( ), a delegate called intDel is instantiated and assigned a reference to Sum( ):
SomeOp<int> intDel = Sum;
BecauseSum( ) takes an int argument and returns an int value, Sum( ) is compatible with 
anint instance of SomeOp.
P
A
R
T
I
Chapter 18: Generics 
541
P
A
R
T
I
P
A
R
T
I
In similar fashion, the delegate strDel is created and assigned a reference to Reflect( ):
SomeOp<string> strDel = Reflect;
BecauseReflect( ) takes a string argument and returns a string result, it is compatible with 
the string version of SomeOp.
Because of the type safety inherent in generics, you cannot assign incompatible methods 
to delegates. For example, assuming the preceding program, the following statement would 
be in error:
SomeOp<int> intDel = Reflect; // Error!
BecauseReflect( ) takes a string argument and returns a string result, it cannot be assigned 
to an int version of SomeOp.
Generic Interfaces
interfaces are specified just like generic classes. Here is an example that reworks the ISeries
interface developed in Chapter 12. (Recall that ISeries defines the interface to a class that 
a type parameter.
// Demonstrate a generic interface.
using System;
public interface ISeries<T> {
T GetNext(); // return next element in series
void Reset(); // restart the series
void SetStart(T v); // set the starting element
}
// Implement ISeries.
class ByTwos<T> : ISeries<T> {
T start;
T val;
// This delegate defines the form of a method
// that will be called when the next element in
// the series is needed.
public delegate T IncByTwo(T v);
// This delegate reference will be assigned the
// method passed to the ByTwos constructor.
IncByTwo incr;
public ByTwos(IncByTwo incrMeth) {
start = default(T);
val = default(T);
incr = incrMeth;
}
542
Part I: The C# Language
public T GetNext() {
val = incr(val);
return val;
}
public void Reset() {
val = start;
}
public void SetStart(T v) {
start = v;
val = start;
}
}
class ThreeD {
public int x, y, z;
public ThreeD(int a, int b, int c) {
x = a;
y = b;
z = c;
}
}
class GenIntfDemo {
// Define plus two for int.
static int IntPlusTwo(int v) {
return v + 2;
}
// Define plus two for double.
static double DoublePlusTwo(double v) {
return v + 2.0;
}
// Define plus two for ThreeD.
static ThreeD ThreeDPlusTwo(ThreeD v) {
if(v==null) return new ThreeD(0, 0, 0);
else return new ThreeD(v.x + 2, v.y + 2, v.z + 2);
}
static void Main() {
// Demonstrate int series.
ByTwos<int> intBT = new ByTwos<int>(IntPlusTwo);
for(int i=0; i < 5; i++)
Console.Write(intBT.GetNext() + "  ");
Console.WriteLine();
P
A
R
T
I
Chapter 18: Generics 
543
P
A
R
T
I
P
A
R
T
I
// Demonstrate double series.
ByTwos<double> dblBT = new ByTwos<double>(DoublePlusTwo);
dblBT.SetStart(11.4);
for(int i=0; i < 5; i++)
Console.Write(dblBT.GetNext() + "  ");
Console.WriteLine();
// Demonstrate ThreeD series.
ByTwos<ThreeD> ThrDBT = new ByTwos<ThreeD>(ThreeDPlusTwo);
ThreeD coord;
for(int i=0; i < 5; i++) {
coord = ThrDBT.GetNext();
Console.Write(coord.x + "," +
coord.y + "," +
coord.z + "  ");
}
Console.WriteLine();
}
}
The output is shown here:
2  4  6  8  10
13.4  15.4  17.4  19.4  21.4
0,0,0  2,2,2  4,4,4  6,6,6  8,8,8
There are several things of interest in the preceding example. First, notice how ISeries is 
declared:
public interface ISeries<T> {
Now, notice how ByTwos, which implements ISeries, is declared:
class ByTwos<T> : ISeries<T> {
The type parameter T is specified by ByTwos and is also specified in ISeries. This is 
important. A
T is not defined:
class ByTwos : ISeries<T> { // Wrong!
The type argument required by the ISeries interface must be passed to ByTwos. Otherwise, 
there is no way for the interface to receive the type argument.
Documents you may be interested
Documents you may be interested