Intro To C#
Intro To C#
H.Mössenböck
University of Linz, Austria
moessenboeck@ssw.uni-linz.ac.at
Contents
Introduction to C# Advanced C#
1. Overview 7. Inheritance
2. Types 8. Interfaces
3. Expressions 9. Delegates
4. Declarations 10. Exceptions
5. Statements 11. Namespaces and Assemblies
6. Classes and Structs 12. Attributes
13. Threads
14. XML Comments
References:
• B.Albahari, P.Drayton, B.Merrill: C# Essentials. O'Reilly, 2001
• S.Robinson et al: Professional C#, Wrox Press, 2001
• Online documentation on the .NET SDK CD
2
Features of C#
As in Java As in C++
• Object-orientation (single inheritance) • (Operator) Overloading
• Interfaces • Pointer arithmetic in unsafe code
• Exceptions • Some syntactic details
• Threads
• Namespaces (like Packages)
• Strong typing
• Garbage Collection
• Reflection
• Dynamic loading of code
• ...
3
New Features in C#
4
Hello World
File Hello.cs
using System;
• uses the namespace System
• entry point must be called Main
class Hello {
• output goes to the console
• file name and class name
static void Main() {
need not be identical
Console.WriteLine("Hello World");
}
5
Structure of C# Programs
Programm
class Prog {
Working with DLLs
static void Main() {
Counter c = new Counter(); csc /target:library Counter.cs
c.Add(3); c.Add(5); => generates Counter.dll
Console.WriteLine("val = " + c.Val());
} csc /reference:Counter.dll Prog.cs
} => generates Prog.exe
7
Types
Unified Type System
Types
9
Value Types versus Reference Types
Value Types Reference Types
variable contains value reference
stored on stack heap
initialisation 0, false, '\0' null
assignment copies the value copies the reference
i 17 s
Hello
j 17 s1
10
Simple Types
Long Form in Java Range
sbyte System.SByte byte -128 .. 127
byte System.Byte --- 0 .. 255
short System.Int16 short -32768 .. 32767
ushort System.UInt16 --- 0 .. 65535
int System.Int32 int -2147483648 .. 2147483647
uint System.UInt32 --- 0 .. 4294967295
long System.Int64 long -263 .. 263-1
ulong System.UInt64 --- 0 .. 264-1
float System.Single float ±1.5E-45 .. ±3.4E38 (32 Bit)
double System.Double double ±5E-324 .. ±1.7E308 (64 Bit)
decimal System.Decimal --- ±1E-28 .. ±7.9E28 (128 Bit)
bool System.Boolean boolean true, false
char System.Char char Unicode character
11
Compatibility Between Simple Types
char
12
Enumerations
List of named constants
Use
13
Operations on Enumerations
The compiler does not check if the result is a valid enumeration value.
Note
- Enumerations cannot be assigned to int (except after a type cast).
- Enumeration types inherit from object (Equals, ToString, ...).
- Class System.Enum provides operations on enumerations
(GetName, Format, GetValues, ...).
14
Arrays
One-dimensional Arrays
15
Multidimensional Arrays
Jagged (like in Java) a
a[0][1]
int x = a[0][1];
int len = a.Length; // 2
len = a[0].Length; // 3
16
Class System.String
Can be used as standard type string
string s = "Alfonso";
Note
• Strings are immutable (use StringBuilder if you want to modify strings)
• Can be concatenated with +: "Don " + s
• Can be indexed: s[i]
• String length: s.Length
• Strings are reference types => reference semantics in assignments
• but their values can be compared with == and != : if (s == "Alfonso") ...
• Class String defines many useful operations:
CompareTo, IndexOf, StartsWith, Substring, ...
17
Structs
Declaration
struct Point {
public int x, y; // fields
public Point (int x, int y) { this.x = x; this.y = y; } // constructor
public void MoveTo (int a, int b) { x = a; y = b; } // methods
}
Use
Point p = new Point(3, 4); // constructor initializes object on the stack
p.MoveTo(10, 20); // method call
18
Classes
Declaration
class Rectangle {
Point origin;
public int width, height;
public Rectangle() { origin = new Point(0,0); width = height = 0; }
public Rectangle (Point p, int w, int h) { origin = p; width = w; height = h; }
public void MoveTo (Point p) { origin = p; }
}
Use
Rectangle r = new Rectangle(new Point(10, 20), 5, 5);
int area = r.width * r.height;
r.MoveTo(new Point(3, 3));
19
Differences Between Classes and Structs
Classes Structs
20
Boxing and Unboxing
Value types (int, struct, enum) are also compatible with object!
Boxing
The assignment
object obj = 3;
wraps up the value 3 into a heap object
obj
Unboxing
The assignment
int x = (int) obj;
unwraps the value again
21
Boxing/Unboxing
Allows the implementation of generic container types
class Queue {
...
public void Enqueue(object x) {...}
public object Dequeue() {...}
...
}
This Queue can then be used for reference types and value types
Queue q = new Queue();
q.Enqueue(new Rectangle());
q.Enqueue(3);
22
Expressions
Operators and their Priority
Primary (x) x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked
Unary + - ~ ! ++x --x (T)x
Multiplicative * / %
Additive + -
Shift << >>
Relational < > <= >= is as
Equality == !=
Logical AND &
Logical XOR ^
Logical OR |
Conditional AND &&
Conditional OR ||
Conditional c?x:y
Assignment = += -= *= /= %= <<= >>= &= ^= |=
24
Overflow Check
Overflow is not checked by default
int x = 1000000;
x = x * x; // -727379968, no error
checked {
...
x = x * x; // Î System.OverflowException
...
}
25
typeof and sizeof
typeof
• Returns the Type descriptor for a given type
(the Type descriptor of an object o can be retrieved with o.GetType()).
Type t = typeof(int);
Console.WriteLine(t.Name); // Î Int32
sizeof
• Returns the size of a type in bytes.
• Can only be applied to value types.
• Can only be used in an unsafe block (the size of structs may be system dependent).
Must be compiled with csc /unsafe xxx.cs
unsafe {
Console.WriteLine(sizeof(int));
Console.WriteLine(sizeof(MyEnumType));
Console.WriteLine(sizeof(MyStructType));
}
26
Declarations
Declaration Space
The program area to which a declaration belongs
Scoping rules
- A name must not be declared twice in the same declaration space.
- Declarations may occur in arbitrary order.
Exception: local variables must be declared before they are used
Visibility rules
- A name is only visible within its declaration space
(local variables are only visible after their point of declaration).
- The visibility can be restricted by modifiers (private, protected, ...)
28
Namespaces
File: X.cs
namespace A {
... Classes ...
... Interfaces ...
... Structs ...
... Enums ...
... Delegates ...
namespace B { // full name: A.B
...
}
}
File: Y.cs
namespace A {
...
namespace B {...}
}
namespace C {...}
using Util.Figures;
class Test {
Rect r; // without qualification (because of using Util.Figures)
Triangle t;
Util.Color c; // with qualification
}
Foreign namespaces
• must either be imported (e.g. using Util;)
• or specified in a qualified name (e.g. Util.Color)
{ // nested block
... local variables ...
}
Note
• The declaration space of a block includes the declaration spaces of nested blocks.
• Formal parameters belong to the declaration space of the method block.
• The loop variable in a for statement belongs to the block of the for statement.
• The declaration of a local variable must precede its use.
31
Declaration of Local Variables
void foo(int a) {
int b;
if (...) {
int b; // error: b already declared in outer block
int c; // ok so far, but wait ...
int d;
...
} else {
int a; // error: a already declared in outer block
int d; // ok: no conflict with d from previous block
}
for (int i = 0; ...) {...}
for (int i = 0; ...) {...} // ok: no conflict with i from previous loop
int c; // error: c already declared in this declaration space
}
32
Statements
Simple Statements
Empty statement
; // ; is a terminator, not a separator
Assigment
x = 3 * y + 1;
Method call
string s = "a,b,c";
string[] parts = s.Split(','); // invocation of an object method (non-static)
34
if Statement
if ('0' <= ch && ch <= '9')
val = ch - '0';
else if ('A' <= ch && ch <= 'Z')
val = 10 + ch - 'A';
else {
val = 0;
Console.WriteLine("invalid character {0}", ch);
}
35
switch Statement
switch (country) {
case "Germany": case "Austria": case "Switzerland":
language = "German";
break;
case "England": case "USA":
language = "English";
break;
case null:
Console.WriteLine("no country specified");
break;
default:
Console.WriteLine("don't know language of {0}", country);
break;
}
int state = 0;
int ch = Console.Read();
switch (state) {
case 0: if (ch == 'a') { ch = Console.Read(); goto case 1; }
else if (ch == 'c') goto case 2;
else goto default;
case 1: if (ch == 'b') { ch = Console.Read(); goto case 1; }
else if (ch == 'c') goto case 2;
else goto default;
case 2: Console.WriteLine("input valid");
break;
default: Console.WriteLine("illegal character {0}", ch);
break;
}
37
Loops
while
while (i < n) {
sum += i;
i++;
}
do while
do {
sum += a[i];
i--;
} while (i > 0);
38
foreach Statement
For iterating over collections and arrays
string s = "Hello";
foreach (char ch in s) Console.WriteLine(ch);
39
Jumps
break; For exiting a loop or a switch statement.
There is no break with a label like in Java (use goto instead).
myLab:
...
goto myLab; Jumps to the label myLab.
Restrictions:
- no jumps into a block
- no jumps out of a finally block of a try statement
40
return Statement
Returning from a void method
void f(int x) {
if (x == 0) return;
...
}
class C {
static int Main() {
...
return errorCode; // The Main method can be declared as a function;
} // the returned error code can be checked with the
// DOS variable errorlevel
}
41
Classes and Structs
Contents of Classes or Structs
class C {
... fields, constants ... // for object-oriented programming
... methods ...
... constructors, destructors ...
43
Classes
class Stack {
int[] values;
int top = 0;
public Stack(int size) { ... }
public void Push(int x) {...}
public int Pop() {...}
}
• Classes can inherit from one other class (single code inheritance)
• Classes can implement multiple interfaces (multiple type inheritance)
44
Structs
struct Point {
int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public MoveTo(int x, int y) {...}
}
• Objects are allocated on the stack not on the heap (structs are value types)
+ efficient, low memory consumption, no burden for the garbage collector.
- live only as long as their container (not suitable for dynamic data structures)
• Can be allocated with new
Point p; // fields of p are not yet initialized
Point q = new Point();
Example
46
Fields and Constants
class C {
Constant
- Value must be computable at compile time
48
Methods
Examples
class C {
int sum = 0, n = 0;
49
Static Methods
Operations on class data (static fields)
class Rectangle {
static Color defaultColor;
50
Parameters
Value Parameters (input values) - "call by value"
void Inc(int x) {x = x + 1;} - formal parameter is a copy of the
void f() { actual parameter
int val = 3; - actual parameter is an expression
Inc(val); // val == 3
}
keyword
array type
params
Use
Add(out sum, 3, 5, 2, 9); // sum == 19
52
Method Overloading
Methods of a class may have the same name
- if they have different numbers of parameters, or
- if they have different parameter types, or
- if they have different parameter kinds (value, ref/out)
Examples
void F (int x) {...}
void F (char x) {...}
void F (int x, long y) {...}
void F (long x, int y) {...}
void F (ref int x) {...}
Calls
int i; long n; short s;
F(i); // F(int x)
F('a'); // F(char x)
F(i, n); // F(int x, long y)
F(n, s); // F(long x, int y);
F(i, s); // cannot distinguish F(int x, long y) and F(long x, int y); => compilation error
F(i, i); // cannot distinguish F(int x, long y) and F(long x, int y); => compilation error
Overloaded methods must not differ only in their function types, in the presence of params
or in ref versus out!
53
Constructors for Classes
Example
class Rectangle {
int x, y, width, height;
public Rectangle (int x, int y, int w, int h) {this.x = x; this.y = y; width = x; height = h; }
public Rectangle (int w, int h) : this(0, 0, w, h) {}
public Rectangle () : this(0, 0, 0, 0) {}
...
}
54
Default Constructor
If no constructor was declared in a class, the compiler generates a
parameterless default constructor:
class C { int x; }
C c = new C(); // ok
55
Constructors for Structs
Example
struct Complex {
double re, im;
public Complex(double re, double im) { this.re = re; this.im = im; }
public Complex(double re) : this (re, 0) {}
...
}
56
Static Constructors
Both for classes and for structs
class Rectangle {
...
static Rectangle() {
Console.WriteLine("Rectangle initialized");
}
}
struct Point {
...
static Point() {
Console.WriteLine("Point initialized");
}
}
• Must be parameterless (also for structs) and have no public or private modifier.
• There must be just one static constructor per class/struct.
• Is invoked once before this type is used for the first time.
57
Destructors
class Test {
~Test() {
... finalization work ...
// automatically calls the destructor of the base class
}
58
Properties
Syntactic sugar for get/set methods
class Data { property type
property name
FileStream s;
x = account.Balance; // ok
account.Balance = ...; // compilation error
60
Indexers
Programmable operator for indexing a collection
class File { type of the name type and name
FileStream s; indexed expression (always this) of the index value
Use
File f = ...;
int x = f[10]; // calls f.get(10)
f[10] = 'A'; // calls f.set(10, 'A')
61
Indexers (other example)
class MonthlySales {
int[] product1 = new int[12];
int[] product2 = new int[12];
...
public int this[int i] { // set method omitted => read-only
get { return product1[i-1] + product2[i-1]; }
}
62
Overloaded Operators
Static method for implementing a certain operator
struct Fraction {
int x, y;
public Fraction (int x, int y) {this.x = x; this.y = y; }
Use
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(3, 4);
Fraction c = a + b; // c.x == 10, c.y == 8
63
Conversion Operators
Implicit conversion
- If the conversion is always possible without loss of precision
- e.g. long = int;
Explicit conversion
- If a run time check is necessary or truncation is possible
- e.g. int = (int) long;
Use
Fraction f = 3; // implicit conversion, f.x == 3, f.y == 1
int i = (int) f; // explicit conversion, i == 3
64
Nested Types
class A {
int x;
B b = new B(this);
public void f() { b.f(); }
public class B {
A a;
public B(A a) { this.a = a; }
public void f() { a.x = ...; ... a.f(); }
}
}
class C {
A a = new A();
A.B b = new A.B(a);
}