0% found this document useful (0 votes)
40 views

Chapter 2 Language Fundamentals

The document discusses data types in .NET and C#. It defines the Common Type System which specifies supported data types for language interoperability. It then lists intrinsic C# data types like integers, floats, decimals and their .NET equivalents. The document also covers type conversions, operators, literals and escape sequences in C#.

Uploaded by

Edmund K.M Tsen
Copyright
© © All Rights Reserved
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views

Chapter 2 Language Fundamentals

The document discusses data types in .NET and C#. It defines the Common Type System which specifies supported data types for language interoperability. It then lists intrinsic C# data types like integers, floats, decimals and their .NET equivalents. The document also covers type conversions, operators, literals and escape sequences in C#.

Uploaded by

Edmund K.M Tsen
Copyright
© © All Rights Reserved
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
You are on page 1/ 15

Chapter 2 Language Fundamentals

Data Type
.NET Framework supports multiple programming languages and code written in one
language may interoperate with code written in other languages. In order to facilitate this
language interoperability, the .NET Framework designer defines the Common Type
System (CTS).
Common Type System (CTS).
The CTS specifies all data types supported by the runtime (that is, the CLR). A
requirement for a program written in one language to be used by programs written in
other languages is that the former should only expose CTS-compliant types.
Table: C# intrinsic types
C# Type
.NET
Size Size Values/Range
Type
(byt (Bits
es) )
byte

Byte

0 to 255.

char

Char

16

Any Unicode character.

bool

Boolean

true or false.

sbyte*

SByte

-128 to 127.

short

Int16

16

-32,768 to 32,767.

ushort*

UInt16

16

0 to 65,535.

int

Int32

32

-2,147,483,648 to 2,147,483,647

uint*

UInt32

32

0 to 4,294,967,295

float

Single

32

-3.402823e38 to 3.402823e38

double

Double

64

-1.79769313486232e308 to
1.79769313486232e308

decimal

Decimal

16

128

1.0 10e28 to 7.9 10e28

long

Int64

32

-9,223,372,036,854,775,808 to
9,223,372,036,854,775,807

ulong*

UInt64

32

0 to 18,446,744,073,709,551,615

string

String

A sequence of characters

object

Object

Base type of all other types

C# is rich enough to support intrinsic data types that are both CTS-compliant and CTSnoncompliant. However, C# codes that expose non-CTS-compliant data types may not
interoperate well with codes written in another language.
The four intrinsic types with an asterisk (sbyte, ushort, uint, ulong) are not CTScompliant,

1/15 : 18/06/14 19:58:29

Floating-Point Literals
Numbers such as 0.4, 1.23, 0.5e10 are floating point numbers. A floating point number
has the following parts:
a whole number part
a decimal point
a fractional part
an optional exponent
In the .NET Framework, there are two types of floating points, float and double.
To express float literals, you use one of the following formats.
Digits . [Digits] [ExponentPart] f_or_F
. Digits [ExponentPart] f_or_F
Digits ExponentPart f_or_F
Digits [ExponentPart] f_or_F

Note that the part in brackets is optional.


To explicitly express a double literal, you can suffix it with D or d.
To write double literals, use one of these formats.
Digits . [Digits] [ExponentPart] [d_or_D]
. Digits [ExponentPart] [d_or_D]
Digits ExponentPart [d_or_D]
Digits [ExponentPart] [d_or_D]

In both floats and doubles, ExponentPart is defined as follows.


ExponentIndicator SignedInteger

where

ExponentIndicator

is either e or E and

SignedInteger

is .

Signopt Digits

and

Sign

is either + or - and a plus sign is optional.

Examples of float literals include the following:


2e1f
8.F
.5f
0F
3.14f
9.0001e+12F

Here are examples of double literals:


2e1
8.
.5
0.0D
3.14
9e-9d
7e123D

As for decimal, append the literal with suffix M,


0.6M
2.0M

2/15 : 18/06/14 19:58:29

Character Literals
Here are character literals that are escape sequences:
'\b'
'\t'
'\\'
'\''
'\"'
'\n'
'\r'

the backspace character


the tab character
the backslash
single quote
double quote
linefeed
carriage return

In addition, C# allows you to escape a Unicode character so that you can express a
Unicode character using a sequence of ASCII characters. For example, the Unicode code
for the character is 2299.
You can write the following character literal to express this character:
''

However, if you do not have the tool to produce that character using your keyboard, you
can escape it like so:
'\u2299'

3/15 : 18/06/14 19:58:29

Primitive Conversions
There are two other kinds of primitive conversions, the widening conversion and the
narrowing conversion.
The Widening Conversion
The widening primitive conversion occurs from one type to another type whose size is
the same or larger than that of the first type
byte to short, int, long, float, or double
short to int, long, float, or double
char to int, long, float, or double
int to long, float, or double
long to float or double
float to double
A widening conversion from an integer type to another integer type will not risk
information loss.
The widening primitive conversion occurs implicitly. You do not need to do anything in
your code.
For example:
int a = 10;
long b = a; // widening conversion

The Narrowing Conversion


The narrowing conversion occurs from a type to a different type that has a smaller size.
Unlike the widening primitive conversion, the arrowing primitive conversion must be
explicit. You need to specify the target type in parentheses.
long a = 10;
int b = (int) a; // narrowing conversion

The narrowing conversion may incur information loss, if the converted value is larger
than the capacity of the target type.

4/15 : 18/06/14 19:58:29

Data Type Conversion (String to Int)


public static void Main( string[] args )
{
int number1; // declare first number to add
Console.Write( "Enter first integer: " ); // prompt user
// read first number from user
number1 = Convert.ToInt32( Console.ReadLine() );
}

ReadLine returns the text the user entered. Then, the string is used as an argument to
class Converts ToInt32 method, which converts this sequence of characters into data of
type int. In this case, method ToInt32 returns the int representation of the users input.

Technically, the user can type anything as the input value. ReadLine will accept it and
pass it off to the ToInt32 method. This method assumes that the string contains a valid
integer value.
In this app, if the user types a noninteger value, a runtime logic error called an
exception will occur and the app will terminate.

5/15 : 18/06/14 19:58:29

Operators
Table list C# operators.
=
==
+
+=

>
<=
-=

<
>=
*
*=

!
!=
/
/=

~
&&
&
&=

?
||
|
|=

:
++
^
^=

-%
%=

<<
<<=

>>
>>=

>>>
>>>=

In C#, there are six categories of operators .


Unary operators
Arithmetic operators
Relational and conditional operators
Shift and logical operators
Assignment operators
Other operators

Unary Operators
Unary operators operate on one operand. There are six unary operators,
Unary Minus Operator
The unary minus operator returns the negative of its operand. The operand must be a
numeric primitive or a variable of a numeric primitive type
float x = 4.5f;
float y = -x;

Unary Plus Operator +


This operator returns the value of its operand. The operand must be a numeric primitive
or a variable of a numeric primitive type.
float x = 4.5f;
float y = +x;

Increment Operator ++
This operator increments the value of its operand by one. The operand must be a
variable of a numeric primitive type.
The operator can appear before or after the operand.
If the operator appears before the operand, it is called the prefix increment operator .
If it is written after the operand, it becomes the postfix increment operator.
As an example, here is a prefix increment operator in action:
int x = 4;
++x;
//After ++x, the value of x is 5.

The preceding code is the same as


int x = 4;
x++;
//After x++, the value of x is 5.

6/15 : 18/06/14 19:58:29

However, if the result of an increment operator is assigned to another variable in the


same expression, there is a difference between the prefix operator and its postfix twin.
Consider this example.
int x = 4;
int y = ++x;
// y = 5, x = 5

The prefix increment operator is applied before the assignment. x is incremented


to 5, and then its value is copied to y.
However, check the use of the postfix increment operator here.
int x = 4;
int y = x++;
// y = 4, x = 5

With the postfix increment operator, the value of the operand (x) is incremented after
the value of the operand is assigned to another variable (y).
Decrement Operator -Similar to above.
Logical Complement Operator !
This operator can only be applied to a bool primitive or an instance of System.Boolean. The
value of this operator is true if the operand isfalse, and false if the operand is true. For
example:
bool x = false;
bool y = !x;
// at this point, y is true and x is false

Bitwise Complement Operator ~


The operand of this operator must be an integer primitive or a variable of an integer
primitive type. The result is the bitwise complement of the operand. For example:
int j = 2;
int k = ~j; // k = -3; j = 2

This is what happens:

0000 0000 0000 0000 0000 0000 0000 0010

Its bitwise complement is


1111 1111 1111 1111 1111 1111 1111 1101

which is the representation of -3 in an integer.


Operator
This unary operator is used to obtain the size of a data type in bytes.
For example,
sizeof

sizeof(int) returns 4.

7/15 : 18/06/14 19:58:29

Arithmetic Operators
There

and

are four types of arithmetic operations:


addition, +
subtraction, multiplication, *
division, /
modulus. %

Equality Operators
There are two equality operators,
== (equal to) and
!= (not equal to),
both operating on two operands that can be integers, floating points, characters, or bool.
The outcome of equality operators is a boolean.
For example,
int a = 5;
int b = 5;
bool c = a == b;

the value of c is true after the comparison.


As another example,
bool x = true;
bool y = true;
bool z = x != y;

The value of z is false after comparison because x is equal to y.

Relational Operators
There are five relational operators:
<, >, <=, and >=.
The <, >, <=, and >= operators operate on two operands whose types must be
convertible to a numeric primitive type. Relational operations return a bool.

Conditional Operators
There are three conditional operators :
AND operator, &&,
OR operator, ||,
? : operator.
The ? : Operator
This operator operates on three operands.
The syntax is
expression1 ? expression2 : expression3
expression1
expression2

must return a value convertible to


is returned.

boolean.

If

expression1

8/15 : 18/06/14 19:58:29

evaluates to true,

Shift Operators
A shift operator takes two operands whose type must be convertible to an integer
primitive.
The left-hand operand is the value to be shifted, the right-hand operand indicates the
shift distance.
There are three types of shift operators:

the left shift operator, <<


the right shift operator, >>
the unsigned right shift operator,

>>>

The Left Shift Operator <<


The left shift operator bit-shifts a number to the left, padding the right bits with 0.
The value of n << s is n left-shifted s bit positions.
This is the same as multiplication by two to the power of s.
For example,
left-shifting an int whose value is 1 with a shift distance of 3 (1 << 3) results in 8.
Again, to figure this out, you convert the operand to a binary number.
0000 0000 0000 0000 0000 0000 0000 0001

Shifting to the left 3 shift units results in:


0000 0000 0000 0000 0000 0000 0000 1000

which is equivalent to 8 (the same as 1 * 23).


Another rule is this.
If the left-hand operand is an int, only the first five bits of the shift distance
will be used.
In other words, the shift distance must be within the range 0 and 31.
If you pass an number greater than 31, only the first five bits will be used.
This is to say, if x is an int, x << 32 is the same as x << 0; x << 33 is the same as x <<
1.
If the left-hand operand is a long, only the first six bits of the shift distance will be used.
In other words, the shift distance actually used is within the range 0 and 63.
The Right Shift Operator >>
The right shift operator >> bit-shifts the left-hand operand to the right.
The value of n >> s is n right-shifted s bit positions. The resulting value is n/2s.
As an example, 16 >> 1 is equal to 8.
To prove this, write the binary representation of 16.
0000 0000 0000 0000 0000 0000 0001 0000

Then, shifting it to the right by 1 bit results in.


0000 0000 0000 0000 0000 0000 0000 1000

which is equal to 8.

9/15 : 18/06/14 19:58:29

The Unsigned Right Shift Operator >>>


The value of n >>> s depends on whether n is positive or negative.
For a positive n, the value is the same as n >> s.
If n is negative, the value depends on the type of n.
If n is an int, the value is (n>>s)+(2<<~s).
If n is a long, the value is (n>>s)+(2L<<~s).

Assignment Operators
There are twelve assignment operators :
=

+=

-=

*=

/=

%=

<<=

>>=

>>>=

&=

^=

|=

Assignment operators take two operands whose type must be of an integral primitive.
The two-part assignment operators work by applying the first operator to both operands
and then assign the result to the left-hand operand.
For example

x += 5 is the same as x = x + 5.
x &= 5 produces the same result as x = x &= 5.

Integer Bitwise Operators & | ^


The bitwise operators & | ^ perform a bit to bit operation on two operands whose types
must be convertible to int.
& indicates an AND operation,
| an OR operation,
^ an exclusive OR operation.
For example,
0xFFFF & 0x0000 = 0x0000
0xF0F0 & 0xFFFF = 0xF0F0

Logical Operators & | ^


The logical operators & | ^ perform a logical operation on two operands that are
convertible to boolean.
& indicates an AND operation,
| an OR operation,
^ an exclusive OR operation.
For example,
true & true = true
true & false = false

10/15 : 18/06/14 19:58:29

Operator Precedence
Table lists all the operators in the order of precedence. Operators in the same column
have equal precedence.
Operator
postfix operators

[ ] . (params) expr++ expr--

unary operators

++expr --expr +expr -expr ~ !

creation or cast

new (type)expr

multiplicative

* / %

additive

+ -

shift

<< >> >>>

relational

< > <= >=

equality

== !=

bitwise AND

&

bitwise exclusive
OR

bitwise inclusive
OR

logical AND

&&

logical OR

||

conditional

? :

assignment

= += -= *= /= %= &= ^= |= <<= >>= >>>=

Promotion
Some unary operators (such as +, -, and ~) and binary operators (such as +, -, *, /) cause
automatic promotion, i.e. elevation to a wider type such as from byte to int.
Consider the following code:
sbyte x = 5;
sbyte y = -x; // error

The second line surprisingly causes an error even though a sbyte can accommodate -5.
The reason for this is the unary operator - causes the result of -x to be promoted to int.
To rectify the problem, either change y to int or perform an explicit narrowing conversion
like this.
sbyte x = 5;
sbyte y = (sbyte) x;

For unary operators, if the type of the operand is byte, sbyte, short, or char, the
outcome is promoted to int.
For binary operators, the promotion rules are as follows.
If any of the operands is of type byte, sbyte, or short, then both operands
will be converted to int and the outcome will be an int.
If any of the operands is of type double, then the other operand is
converted to double and the outcome will be a double.

11/15 : 18/06/14 19:58:29

If any of the operands is of type float, then the other operand is converted
to float and the outcome will be a float.
If any of the operands is of type long, then the other operand is converted
to long and the outcome will be a long.

For example, the following code causes a compile error:


short x = 200;
short y = 400;
short z = x + y;

You can fix this by changing z to int or perform an explicit narrowing conversion of x + y,
such as
short z = (short) (x + y);

Note that the parentheses around x + y is required, otherwise only x would be converted
to int and the result of addition of a short and an int will be an int.

12/15 : 18/06/14 19:58:29

Variable: Constant Variable


In C# you can prefix a variable declaration with the keyword const to make its value
unchangeable. Constants must be initialized to a constant value when theyre declared.
For example,
const float pi = (float) 22 / 7;

Also note that since C# uses Unicode characters, you can simply define the variable pi as
if you dont think typing it is harder than typing pi.
const float = (float) 22 / 7;

Variables: readonly Instance Variables


(refer to Chapter 4: Class and Object).

Comments
There are two types of comments in C#, both with syntax similar to comments in C and
C++.
Traditional comments. Enclose a traditional comment in /* and */.
End-of-line comments. Use double slashes (//) which causes the rest of the
line after // to be ignored by the compiler.

For example, here is a comment that describes a method


/*
toUpperCase capitalizes the characters of in a String object
*/
public void toUpperCase(String s) {

Here is an end-of-line comment:


public int rowCount; //the number of rows from the database

Traditional comments do not nest, which means


/*
/* comment 1 */
comment 2 */

On the other hand, end-of-line comments can contain anything, including the sequences
of characters /* and */, such as this:
// /* this comment is okay */

13/15 : 18/06/14 19:58:29

Simple-Type

14/15 : 18/06/14 19:58:29

Simple-Type structs
Each simple type (see Table, Simple Types) has a corresponding struct in namespace
System that defines the simple type.
These structs are called Boolean, Byte, SByte, Char, Decimal, Double, Single, Int16, Uint16,
Int32, UInt32, Int64 and Uint64. (Refer to section Data Type above). Types declared with
keyword struct are value types.
Simple types are actually aliases for their corresponding structs, so a variable of a
simple type can be declared using either
the keyword for that simple type or
the struct name
e.g., int and Int32 are interchangeable.
The methods related to a simple type are located in the corresponding struct (e.g.,
method Parse, which converts a string to an int value, is located in struct Int32).

Boxing and Unboxing Conversions


Simple types and other structs inherit from class ValueType in namespace System.
Class ValueType inherits from class object.
Thus, any simple-type value can be assigned to an object variable; this is referred to as a
boxing conversion and enables simple types to be used anywhere objects are
expected.

Boxing (simple-type)
In a boxing conversion, the simple-type value is copied into an object so that
the simple-type value can be manipulated as an object.
Boxing conversions can be performed either explicitly or implicitly as shown in the
following statements:
int i = 5; // create an int value
object object1 = ( object ) i; // explicitly box the int value
object object2 = i; // implicitly box the int value

After executing the preceding code, both object1 and object2 refer to two different
objects that contain a copy of the integer value in int variable i.

Unboxing(simple-type)
An unboxing conversion can be used to explicitly convert an object reference
to a simple value,
int int1 = ( int ) object1; // explicitly unbox the int value

Explicitly attempting to unbox an object reference that does not refer to the correct
simple value type causes an InvalidCastException.

15/15 : 18/06/14 19:58:29

You might also like