Saturday, 27 October 2012

Primitives-

The next three sections of this chapter describe features that you'll find in most programming languages: variables and data types, operators, expressions, and statements that control the flow of operations. The discussion begins with primitives. As the name implies, these are the core C# data types used as building blocks for more complex class and structure types. Variables of this type contain a single value and always have the same predefined size. Table 2-3 provides a formal list of primitives, their corresponding core data types, and their sizes.
Table 2-3. C# Primitive Data Types
C# Primitive Type
FCL Data Type
Description
object
System.Object
Ultimate base type of all other types.
string
System.String
A sequence of Unicode characters.
decimal
System.Decimal
Precise decimal with 28 significant digits.
bool
System.Boolean
A value represented as true or false.
char
System.Char
A 16-bit Unicode character.
byte
System.Byte
8-bit unsigned integral type.
sbyte
System.SByte
8-bit signed integral type.
short
System.Int16
16-bit signed integral type.
int
System.Int32
32-bit signed integral type.
long
System.Int64
64-bit signed integral type.
ushort
System.UInt16
16-bit unsigned integral type.
uint
System.UInt32
32-bit unsigned integral type.
ulong
System.UIint64
64-bit unsigned integral type.
single (float)
System.Single
Single-precision floating-point type.
double
System.Double
Double-precision floating-point type.


As the table shows, primitives map directly to types in the base class library and can be used interchangeably. Consider these statements:
System.Int32 age = new System.Int32(17);

int age = 17; 

System.Int32 age = 17;


They all generate exactly the same Intermediate Language (IL) code. The shorter version relies on C# providing the keyword int as an alias for the System.Int32 type. C# performs aliasing for all primitives.
Here are a few points to keep in mind when working with primitives:
  • The keywords that identify the value type primitives (such as int) are actually aliases for an underlying structure (struct type in C#). Special members of these structures can be used to manipulate the primitives. For example, the Int32 structure has a field that returns the largest 32-bit integer and a method that converts a numeric string to an integer value:
    int iMax = int.MaxValue;     // Return largest integer 
    
    int pVal = int.Parse("100"); // converts string to int
    
    

    The C# compiler supports implicit conversions if the conversion is a "safe" conversion that results in no loss of data. This occurs when the target of the conversion has a greater precision than the object being converted, and is called a widening conversion. In the case of a narrowing conversion, where the target has less precision, the conversion must have explicit casting. Casting is used to coerce, or convert, a value of one type into that of another. This is done syntactically by placing the target data type in parentheses in front of the value being converted: int i = (int)y;.
    short i16 = 50;    // 16-bit integer
    
    int i32 = i16;     // Okay: int has greater precision
    
    i16 = i32;         // Fails: short is 16 bit, int is 32
    
    i16 = (short) i32; // Okay since casting used
    
    

  • Literal values assigned to the types float, double, and decimal require that their value include a trailing letter: float requires F or f; double has an optional D or d; and decimal requires M or m.
    decimal pct = .15M; // M is required for literal value
    
    
The remainder of this section offers an overview of the most useful primitives with the exception of string, which is discussed later in the chapter.

decimal

The decimal type is a 128-bit high-precision floating-point number. It provides 28 decimal digits of precision and is used in financial calculations where rounding cannot be tolerated. This example illustrates three of the many methods available to decimal type. Also observe that when assigning a literal value to a decimal type, the M suffix must be used.
decimal iRate = 3.9834M;         // decimal requires M 

iRate = decimal.Round(iRate,2);  // Returns 3.98

decimal dividend = 512.0M;

decimal divisor = 51.0M;

decimal p = decimal.Parse("100.05");

// Next statement returns remainder = 2

decimal rem = decimal.Remainder(dividend,divisor);


bool

The only possible values of a bool type are true and false. It is not possible to cast a bool value to an integer—for example, convert true to a 1, or to cast a 1 or 0 to a bool.
bool bt = true;

string bStr = bt.ToString(); // returns "true"

bt = (bool) 1;               // fails


char

The char type represents a 16-bit Unicode character and is implemented as an unsigned integer. A char type accepts a variety of assignments: a character value placed between individual quote marks (' '); a casted numeric value; or an escape sequence. As the example illustrates, char also has a number of useful methods provided by the System.Char structure:
myChar =  'B';       // 'B' has an ASCII value of 66

myChar = (char) 66;  // Equivalent to 'B'

myChar = '\u0042';   // Unicode escape sequence

myChar = '\x0042';   // Hex escape sequence

myChar = '\t';       // Simple esc sequence:horizontal tab

bool bt;

string pattern = "123abcd?";

myChar = pattern[0];                  // '1'

bt = char.IsLetter(pattern,3);        // true  ('a')

bt = char.IsNumber(pattern,3);        // false

bt = char.IsLower(pattern,0);         // false ('1')

bt = char.IsPunctuation(pattern,7);   // true  ('?')

bt = char.IsLetterOrDigit(pattern,1); // true

bt = char.IsNumber(pattern,2);        // true  ('3')

string kstr="K";

char k = char.Parse(kstr);


byte, sbyte

A byte is an 8-bit unsigned integer with a value from 0 to 255. An sbyte is an 8-bit signed integer with a value from –128 to 127.
byte[] b = {0x00, 0x12, 0x34, 0x56, 0xAA, 0x55, 0xFF};

string s = b[4].ToString(); // returns 170

char myChar = (char) b[3];


short, int, long

These represent 16-, 32-, and 64-bit signed integer values, respectively. The unsigned versions are also available (ushort, uint, ulong).
short i16 = 200;

i16 = 0xC8 ;     // hex value for 200

int i32 = i16;   // no casting required 


single, double

These are represented in 32-bit single-precision and 64-bit double-precision formats. In .NET 1.x, single is referred to as float.
  • The single type has a value range of 1.5 x 10 –45 to 3.4 x 1038 with 7-decimal digit precision.
  • The double type has a value range of 5 x 10–324 to 1.7 x 10308 with 15- to 16-decimal digit precision.
  • Floating-point operations return NaN (Not a Number) to signal that the result of the operation is undefined. For example, dividing 0.0 by 0.0 results in NaN.
  • Use the System.Convert method when converting floating-point numbers to another type.
float xFloat = 24567.66F;

int xInt = Convert.ToInt32(xFloat);  // returns 24567

int xInt2 = (int) xFloat;

if(xInt == xInt2) {  }               // False

string xStr = Convert.ToString(xFloat);

single zero = 0;

if (Single.IsNaN(0 / zero)) {  }     // True

double xDouble = 124.56D;


Note that the F suffix is used when assigning a literal value to a single type, and D is optional for a double type.

Using Parse and TryParse to Convert a Numeric String

The primitive numeric types include Parse and tryParse methods that are used to convert a string of numbers to the specified numeric type. This code illustrates:
short shParse  = Int16.Parse("100");

int iParse     = Int32.Parse("100");

long lparse    = Int64.Parse("100");

decimal dParse = decimal.Parse("99.99");

float sParse   = float.Parse("99.99");

double dbParse = double.Parse("99.99");


TRyParse, introduced in .NET 2.0, provides conditional parsing. It returns a boolean value indicating whether the parse is successful, which provides a way to avoid formal exception handling code. The following example uses an Int32 type to demonstrate the two forms of tryParse:
int result;

// parse string and place result in result parameter

bool ok = Int32.TryParse("100", out result); 

bool ok = Int32.TryParse("100", NumberStyles.Integer, null,

                         out result);


In the second form of this method, the first parameter is the text string being parsed, and the second parameter is a NumberStyles enumeration that describes what the input string may contain. The value is returned in the fourth parameter.

C# Get Started

C# Language Fundamentals

Topics
Overview of a C# Program: In addition to the basic elements that comprise a C# program, a developer needs to be aware of other .NET features such as commenting options and recommended naming conventions.
  • Primitives: Primitives are the basic data types defined by the FCL to represent numbers, characters, and dates.
  • Operators: C# uses traditional operator syntax to perform arithmetic and conditional operations.
  • Program Flow Statements: Program flow can be controlled using if and switch statements for selection; and while, do, for, and foreach clauses for iteration.
  • String: The string class supports the expected string operations: concatenation, extracting substrings, searching for instances of a character pattern, and both case sensitive and insensitive comparisons.
  • Enums: An enumeration is a convenient way to assign descriptions that can be used to reference an underlying set of values.
  • Using Arrays: Single- or multi-dimensional arrays of any type can be created in C#. After an array is created, the System.Array class can be used to sort and copy the array.
  • Reference and Value Types: All types in .NET are either a value or reference type. It is important to understand the differences and how they can affect a program's performance.

2.1. The Layout of a C# Program

Figure 2-1 illustrates some of the basic features of a C# program.
Figure 2-1. Basic elements of a C# program


The code in Figure 2-1 consists of a class MyApp that contains the program logic and a class Apparel that contains the data. The program creates an instance of Apparel and assigns it to myApparel. This object is then used to print the values of the class members FabType and Price to the console. The important features to note include the following:
  1. The using statement specifies the namespace System. Recall from Chapter 1, "Introduction to .NET and C#," that the .NET class libraries are organized into namespaces and that the System namespace contains all of the simple data types. The using statement tells the compiler to search this namespace when resolving references, making it unnecessary to use fully qualified names. For example, you can refer to label rather than System.Web.UI.WebControls.Label.
  2. All programming logic and data must be contained within a type definition. All program logic and data must be embedded in a class, structure, enum, interface, or delegate. Unlike Visual Basic, for instance, C# has no global variable that exists outside the scope of a type. Access to types and type members is strictly controlled by access modifiers. In this example, the access modifier public permits external classes—such as MyApp—to access the two members of the Apparel class.
  3. A Main() method is required for every executable C# application. This method serves as the entry point to the application; it must always have the static modifier and the M must be capitalized. Overloaded forms of Main()define a return type and accept a parameter list as input.
    Return an integer value:
    static int Main()
    
    {
    
       return 0; // must return an integer value
    
    }
    
    

    Receive a list of command-line arguments as a parameter and return an integer value:
    static int Main(string[] args)
    
    {
    
       // loop through arguments
    
       foreach(string myArg in args)
    
          Console.WriteLine(myArg);
    
       return 0;
    
    }
    
    

    The parameter is a string array containing the contents of the command line used to invoke the program. For example, this command line executes the program MyApparel and passes it two parameter values:
    C:\> MyApparel 5 6
    
    
Core Note
The contents of the command line are passed as an argument to the Main() method. The System.Environment.CommandLine property also exposes the command line's contents.

General C# Programming Notes

Case Sensitivity
All variable and keywords are distinguished by case sensitivity. Replace class with Class in Figure 2-1 and the code will not compile.
Naming Conventions
The ECMA standard provides naming convention guidelines to be followed in your C# code. In addition to promoting consistency, following a strict naming policy can minimize errors related to case sensitivity that often result from undisciplined naming schemes. Table 2-1 summarizes some of the more important recommendations.
Table 2-1. C# Naming Conventions
Type
Case
Notes and Examples
Class
Pascal
  • Use noun or noun phrases.
  • Try to avoid starting with I because this is reserved for interfaces.
  • Do not use underscores.
Constant
Pascal
public const double GramToPound = 454.0 ;
Enum Type
Pascal
  • Use Pascal case for the enum value names.
  • Use singular name for enums.
public enum WarmColor { Orange, Yellow, Brown}
Event
Pascal
  • The method that handles events should have the suffix EventHandler.
  • Event argument classes should have the suffix EventArgs.
Exception
Pascal
  • Has suffix Exception.
Interface
Pascal
  • Has prefix of I.
IDisposable
Local Variable
Camel
  • Variables with public access modifier use Pascal
int myIndex.
Method
Pascal
  • Use verb or verb phrases for name.
Namespace
Pascal
  • Do not have a namespace and class with the same name.
  • Use prefixes to avoid namespaces having the same name. For example, use a company name to categorize namespaces developed by that company.
Acme.GraphicsLib
Property
Pascal
  • Use noun or noun phrase.
Parameter
Camel
  • Use meaningful names that describe the parameter's purpose.


Note that the case of a name may be based on two capitalization schemes:
  1. Pascal. The first character of each word is capitalized (for example, MyClassAdder).
  2. Camel. The first character of each word, except the first, is capitalized (for example, myClassAdder).
The rule of thumb is to use Pascal capitalization everywhere except with parameters and local variables.
Commenting a C# Program
The C# compiler supports three types of embedded comments: an XML version and the two single-line (//) and multi-line (/* */) comments familiar to most programmers:
//   for a single line 

/*   for one or more lines

                      */

/// <remarks> XML comment describing a class </remarks>


An XML comment begins with three slashes (///) and usually contains XML tags that document a particular aspect of the code such as a structure, a class, or class member. The C# parser can expand the XML tags to provide additional information and export them to an external file for further processing.

Table 2-2. XML Documentation Tags
Tag
Description
<example>
Text illustrating an example of using a particular program feature goes between the beginning and ending tags.
<exception cref="Excep">
cref attribute contains name of exception.
///<exceptioncref="NoParmException">

</exception>

<include file="myXML">
file attribute is set to name of another XML file that is to be included in the XML documentation produced by this source code.
<param name="parm1">
name attribute contains the name of the parameter.
<permission cref= "">
Most of the time this is set to the following:
///<permissioncref="System.Security.Permis-

sionSet"> </permission>

<remarks>
Provides additional information about a type not found in the <summary> section.
<returns>
Place a textual description of what is returned from a method or property between the beginning and ending tags.
<seealso cref="price">
The cref attribute is set to the name of an associated type, field, method, or other type member.
<summary>
Contains a class description; is used by IntelliSense in VisualStudio.NET.


The value of the XML comments lies in the fact that they can be exported to a separate XML file and then processed using standard XML parsing techniques. You must instruct the compiler to generate this file because it is not done by default.
The following line compiles the source code consoleapp.cs and creates an XML file consoleXML:
C:\> csc consoleapp.cs /doc:consoleXML.xml

C# Language Fundamentals

Topics
Overview of a C# Program: In addition to the basic elements that comprise a C# program, a developer needs to be aware of other .NET features such as commenting options and recommended naming conventions.
  • Primitives: Primitives are the basic data types defined by the FCL to represent numbers, characters, and dates.
  • Operators: C# uses traditional operator syntax to perform arithmetic and conditional operations.
  • Program Flow Statements: Program flow can be controlled using if and switch statements for selection; and while, do, for, and foreach clauses for iteration.
  • String: The string class supports the expected string operations: concatenation, extracting substrings, searching for instances of a character pattern, and both case sensitive and insensitive comparisons.
  • Enums: An enumeration is a convenient way to assign descriptions that can be used to reference an underlying set of values.
  • Using Arrays: Single- or multi-dimensional arrays of any type can be created in C#. After an array is created, the System.Array class can be used to sort and copy the array.
  • Reference and Value Types: All types in .NET are either a value or reference type. It is important to understand the differences and how they can affect a program's performance.