504
Part I: The C# Language
Let’s begin with an example:
// Demonstrate the Conditional attribute.
#define TRIAL
using System;
using System.Diagnostics;
class Test {
[Conditional("TRIAL")]
void Trial() {
Console.WriteLine("Trial version, not for distribution.");
}
[Conditional("RELEASE")]
void Release() {
Console.WriteLine("Final release version.");
}
static void Main() {
Test t = new Test();
t.Trial(); // called only if TRIAL is defined
t.Release(); // called only if RELEASE is defined
}
}
The output from this program is shown here:
Trial version, not for distribution.
Let’s look closely at this program to understand why this output is produced. First, 
notice the program defines the symbol TRIAL. Next, notice how the methods Trial( ) and 
Release( ) are coded. They are both preceded with the Conditional attribute, which has this 
general form:
[Conditionalsymbol]
where symbol
defined, then the method is not executed.
InsideMain( ), both Trial( ) and Release( ) are called. However, only TRIAL is defined. 
Thus,Trial( ) is executed. The call to Release( ) is ignored. If you define RELEASE, then 
Release( ) will also be called. If you remove the definition for TRIAL, then Trial( ) will not 
be called.
TheConditional
inheritsAttributeed 
during compilation, the attribute is applied. Otherwise, it is not.
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
reader combine pdf; add pdf files together online
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
break pdf file into multiple files; merge pdf
P
A
R
T
I
Chapter 17: Runtime Type ID, Reflection, and Attributes 
505
P
A
R
T
I
P
A
R
T
I
Conditional methods have a few restrictions. First, they must return void. Second, they 
must be members of a class or structure, not an interface. Third, they cannot be preceded 
with the override keyword.
The Obsolete Attribute
TheObsolete attribute, which is short for System.ObsoleteAttribute, lets you mark a 
program element as obsolete. Here is one of its forms:
[Obsolete(“message”)]
Here, message is displayed when that program element is compiled. Here is a short example:
// Demonstrate the Obsolete attribute.
using System;
class Test {
[Obsolete("Use MyMeth2, instead.")]
public static int MyMeth(int a, int b) {
return a / b;
}
// Improved version of MyMeth.
public static int MyMeth2(int a, int b) {
return b == 0 ? 0 : a /b;
}
static void Main() {
// Warning displayed for this.
Console.WriteLine("4 / 3 is " + Test.MyMeth(4, 3));
// No warning here.
Console.WriteLine("4 / 3 is " + Test.MyMeth2(4, 3));
}
}
When the call to MyMeth( ) is encountered in Main( ) when this program is compiled, 
a warning will be generated that tells the user to use MyMeth2( ) instead.
A second form of Obsolete is shown here:
[Obsolete(“message”,error)]
Here, error is a Boolean value. If it is true, then use of the obsolete item generates a 
compilation error rather than a warning. The difference is, of course, that a program 
containing an error cannot be compiled into an executable program.
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.
pdf merge files; best pdf merger
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
append pdf; c# merge pdf files into one
This page intentionally left blank 
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
add pdf together; pdf merger online
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
append pdf files reader; combine pdf files
18
Generics
T
es: 
generics.
Interestingly, although generics are now an indispensable part of C# programming, 
they were not included in the original 1.0 release. Instead, they were added by C# 2.0. 
and resulted in many changes and upgrades to the library. Although it has been a few years 
since the inclusion of generics in C#, the effects still reverberate throughout the language.
The generics feature is so important because it enables the creation of classes, structures, 
data. As you may know, many algorithms are logically the same no matter what type of 
data they ar
same whether the queue is storing items of type int,string,object, or a user-defined class. 
Prior to generics, you might have created several different versions of the same algorithm to 
handle different types of data. Through the use of generics, you can define a solution once, 
data types without any additional effort.
This chapter describes the syntax, theory, and use of generics. It also shows how generics 
provide type safety for some previously difficult cases. Once you have completed this chapter, 
you will want to examine Chapter 25, which covers Collections. There you will find many 
examples of generics at work in the generic collection classes.
What Are Generics?
At its core, the term generics means parameterizedtypes. Parameterized types are important 
because they enable you to create classes, structures, interfaces, methods, and delegates in 
. Using generics, 
it is possible to create a single class, for example, that automatically works with different 
types of data. A class, structure, interface, method, or delegate that operates on a parameterized 
type is called generic, as in genericclass or generic method.
eate generalized 
code by operating through references of type object. Because object is the base class of all 
other classes, an object reference can refer to any type of object. Thus, in pre-generics code, 
generalized code used object references to operate on a variety of different kinds of objects. 
507
CHAPTER
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
attach pdf to mail merge; acrobat reader merge pdf files
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
c# combine pdf; acrobat merge pdf files
508
Part I: The C# Language
The problem was that it could not do so with type safety because casts were needed to convert 
between the object type and the actual type of the data. This was a potential source of errors 
because it was possible to accidentally use an incorrect cast. Generics avoid this problem by 
providing the type safety that was lacking. Generics also streamline the process because it is 
no longer necessary to employ casts to translate between object and the type of data that is 
actually being operated upon. Thus, generics expand your ability to re-use code, and let 
you do so safely and easily.
N
OTE
N
OTE
A Warning to C++ and Java Programmers:  Although C# generics are similar to templates 
in C++ and generics in Java, they are not the same as either. In fact, there are some fundamental 
differences among these three approaches to generics. If you have a background in C++ or Java, it 
is important to not jump to conclusions about how generics work in C#.
A Simple Generics Example
ogram defines two 
classes. The first is the generic class Gen, and the second is GenericsDemo, which uses Gen.
// A simple generic class.
using System;
// In the following Gen class, T is a type parameter
// that will be replaced by a real type when an object
// of type Gen is created.
class Gen<T> {
T ob; // declare a variable of type T
// Notice that this constructor has a parameter of type T.
public Gen(T o) {
ob = o;
}
// Return ob, which is of type T.
public T GetOb() {
return ob;
}
// Show type of T.
public void ShowType() {
Console.WriteLine("Type of T is " + typeof(T));
}
}
// Demonstrate the generic class.
class GenericsDemo {
static void Main() {
// Create a Gen reference for int.
Gen<int> iOb;
// Create a Gen<int> object and assign its reference to iOb.
iOb = new Gen<int>(102);
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
batch pdf merger; reader merge pdf
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
c# merge pdf pages; pdf mail merge plug in
P
A
R
T
I
Chapter 18: Generics 
509
P
A
R
T
I
P
A
R
T
I
// Show the type of data used by iOb.
iOb.ShowType();
// Get the value in iOb.
int v = iOb.GetOb();
Console.WriteLine("value: " + v);
Console.WriteLine();
// Create a Gen object for strings.
Gen<string> strOb = new Gen<string>("Generics add power.");
// Show the type of data stored in strOb.
strOb.ShowType();
// Get the value in strOb.
string str = strOb.GetOb();
Console.WriteLine("value: " + str);
}
}
The output produced by the program is shown here:
Type of T is System.Int32
value: 102
Type of T is System.String
value: Generics add power.
Let’s examine this program carefully.
First, notice how Gen is declared by the following line.
class Gen<T> {
Here, T is the name of a typeparameter. This name is used as a placeholder for the actual 
type that will be specified when a Gen object is created. Thus, T is used within Gen whenever 
the type parameter is needed. Notice that T is contained within < >. This syntax can be 
generalized. Whenever a type parameter is being declared, it is specified within angle brackets. 
BecauseGen uses a type parameter, Gen is a generic class.
In the declaration of Gen, there is no special significance to the name T. Any valid 
identifier could have been used, but T is traditional. Other commonly used type parameter 
names include V and E. Of course, you can also use descriptive names for type parameters, 
such as TValue or TKey. When using a descriptive name, it is common practice to use T as 
the first letter.
Next,T is used to declare a variable called ob, as shown here:
T ob; // declare a variable of type T
As explained, T is a placeholder for the actual type that will be specified when a Gen object 
is created. Thus, ob will be a variable of the type boundtoT when a Gen object is instantiated. 
For example, if type string is specified for T, then in that instance, ob will be of type string.
510
Part I: The C# Language
Now consider Gen’s constructor:
public Gen(T o) {
ob = o;
}
Notice that its parameter, o, is of type T. This means that the actual type of o is determined 
by the type bound to T when a Gen object is created. Also, because both the parameter o
and the instance variable ob are of type T, they will both be of the same actual type when a 
Gen object is created.
The type parameter T can also be used to specify the return type of a method, as is the 
case with the GetOb( ) method, shown here:
public T GetOb() {
return ob;
}
Becauseob is also of type T, its type is compatible with the return type specified by GetOb( ).
TheShowType( ) method displays the type of T by passing T to the typeof operator. 
Because a real type will be substituted for T when an object of type Gen is created, typeof
will obtain type information about the actual type.
TheGenericsDemoclass demonstrates the generic Gen class. It first creates a version of 
Gen for type int, as shown here:
Gen<int> iOb;
Look closely at this declaration. First, notice that the type int is specified within the angle 
brackets after Gen. In this case, int is a type argument that is bound to Gen’s type parameter, 
T. This creates a version of Gen in which all uses of T are replaced by int. Thus, for this 
declaration,ob is of type int, and the return type of GetOb( ) is of type int.
The next line assigns to iOb a reference to an instance of an int version of the Gen class:
iOb = new Gen<int>(102);
Notice that when the Gen constructor is called, the type argument int is also specified. This 
is necessary because the type of the variable (in this case iOb) to which the reference is being 
assigned is of type Gen<int>. Thus, the reference returned by new must also be of type 
Gen<int>. If it isn’t, a compile-time error will result. For example, the following assignment 
will cause a compile-time error:
iOb = new Gen<double>(118.12); // Error!
BecauseiOb is of type Gen<int>, it can’t be used to refer to an object of Gen<double>. This 
type checking is one of the main benefits of generics because it ensures type safety.
The program then displays the type of ob within iOb, which is System.Int32. This is the 
.NET structure that corresponds to int. Next, the program obtains the value of ob by use of 
the following line:
int v = iOb.GetOb();
Because the return type of GetOb( ) is T, which was replaced by int when iOb was declared, 
the return type of GetOb( ) is also int. Thus, this value can be assigned to an int variable.
P
A
R
T
I
Chapter 18: Generics 
511
P
A
R
T
I
P
A
R
T
I
Next,GenericsDemo declares an object of type Gen<string>:
Gen<string> strOb = new Gen<string>("Generics add power.");
Because the type argument is string,string is substituted for T inside Gen. This creates a 
string version of Gen, as the remaining lines in the program demonstrate.
Before moving on, a few terms need to be defined. When you specify a type argument 
such as int or string for Gen, you are creating what is referred to in C# as a closedconstructed
type. Thus, Gen<int> is a closed constructed type. In essence, a generic type, such as 
Gen<T>, is an abstraction. It is only after a specific version, such as Gen<int>, has been 
constructed that a concrete type has been created. In C# terminology, a construct such as 
Gen<T> is called an open constructed type, because the type parameter T (rather than an 
actual type, such as int) is specified.
More generally, C# defines the concepts of an opentype and a closedtype. An open type is 
a type parameter or any generic type whose type argument is (or involves) a type parameter. 
Any type that is not an open type is a closed type. A constructed type is a generic type for 
which all type arguments have been supplied. If those type arguments are all closed types, 
then it is a closed constructed type. If one or more of those type arguments are open types, 
it is an open constructed type.
Generic Types Differ Based on Their Type Arguments
A key point to understand about generic types is that a reference of one specific version of a 
assuming the program just shown, the following line of code is in error and will not compile:
iOb = strOb; // Wrong!
Even though both iOb and strObare of type Gen<T>, they are references to different types 
because their type arguments differ.
How Generics Improve Type Safety
functionality found in the generic Gen class can be achieved without generics, by simply 
specifyingobject as the data type and employing the proper casts, what is the benefit of 
makingGen generic? The answer is that generics automatically ensure the type safety of all 
operations involving Gen. In the process, generics eliminate the need for you to use casts 
and type-check code by hand.
To understand the benefits of generics, first consider the following program that creates 
a non-generic equivalent of Gen:
// NonGen is functionally equivalent to Gen but does not use generics.
using System;
class NonGen {
object ob; // ob is now of type object
// Pass the constructor a reference of type object.
public NonGen(object o) {
512
Part I: The C# Language
ob = o;
}
// Return type object.
public object GetOb() {
return ob;
}
// Show type of ob.
public void ShowType() {
Console.WriteLine("Type of ob is " + ob.GetType());
}
}
// Demonstrate the non-generic class.
class NonGenDemo {
static void Main() {
NonGen iOb;
// Create NonGen object.
iOb = new NonGen(102);
// Show the type of data stored in iOb.
iOb.ShowType();
// Get the value in iOb.
// This time, a cast is necessary.
int v = (int) iOb.GetOb();
Console.WriteLine("value: " + v);
Console.WriteLine();
// Create another NonGen object and store a string in it.
NonGen strOb = new NonGen("Non-Generics Test");
// Show the type of data stored in strOb.
strOb.ShowType();
// Get the value of strOb.
// Again, notice that a cast is necessary.
String str = (string) strOb.GetOb();
Console.WriteLine("value: " + str);
// This compiles, but is conceptually wrong!
iOb = strOb;
// The following line results in a runtime exception.
// v = (int) iOb.GetOb(); // runtime error!
}
}
This program produces the following output:
Type of ob is System.Int32
value: 102
P
A
R
T
I
Chapter 18: Generics 
513
P
A
R
T
I
P
A
R
T
I
Type of ob is System.String
value: Non-Generics Test
As you can see, the output is similar to the previous version of the program.
There are several things of interest in this version. First, notice that NonGen replaces all 
uses of T with object. This makes NonGen able to store any type of object, as can the generic 
version. However, this approach is bad for two reasons. First, explicit casts must be employed 
to retrieve the stored data. Second, many kinds of type mismatch errors cannot be found 
until runtime. Let’s look closely at each problem.
We will begin with this line:
int v = (int) iOb.GetOb();
Because the return type of GetOb( ) is now object, the cast to int is necessary to enable 
the value returned by GetOb( ) to be unboxed and stored in v. If you remove the cast, the 
program will not compile. In the generic version of the program, this cast was not needed 
becauseint was specified as a type argument when iOb was constructed. In the non-generic 
source of error.
Now, consider the following sequence from near the end of the program:
// This compiles, but is conceptually wrong!
iOb = strOb;
// The following line results in a runtime exception.
// v = (int) iOb.GetOb(); // runtime error!
Here, strOb is assigned to iOb. However, strOb refers to an object that contains a string, not 
an integer. This assignment is syntactically valid because all NonGen references are the same, 
and any NonGen reference can refer to any other NonGen object. However, the statement is 
semantically wrong, as the commented-out line shows. In that line, the return type of GetOb( )
is cast to int and then an attempt is made to assign this value to v. The trouble is that iOb
now refers to an object that stores a string, not an int. Unfortunately, without generics, the 
compiler won’t catch this error. Instead, a runtime exception will occur when the cast to int
is attempted. To see this for yourself, try removing the comment symbol from the start of 
the line and then compiling and running the program. A runtime error will occur.
The preceding sequence can’t occur when generics are used. If this sequence were 
attempted in the generic version of the program, the compiler would catch it and report 
an error, thus preventing a serious bug that results in a runtime exception. The ability to 
create type-safe code in which type-mismatch errors are caught at compile time is a key 
advantage of generics. Although using object references to create “generic” code has always 
been possible in C#, that code was not type-safe and its misuse could result in runtime 
exceptions. Generics prevent this from occurring. In essence, through generics, what 
were once runtime errors have become compile-time errors. This is a major benefit.
There is one other point of interest in the NonGen program. Notice how the type of the 
NonGen instance variable ob is obtained by ShowType( ):
Console.WriteLine("Type of ob is " + ob.GetType());
Recall from Chapter 11 that object defines several methods that are available to all data types. 
One of these methods is GetType( ), which returns a Type object that describes the type of 
Documents you may be interested
Documents you may be interested