Presentation is loading. Please wait.

Presentation is loading. Please wait.

C# The new language for Updated by Pavel Ježek

Similar presentations


Presentation on theme: "C# The new language for Updated by Pavel Ježek"— Presentation transcript:

1 C# The new language for Updated by Pavel Ježek
© University of Linz, Institute for System Software, 2004 published under the Microsoft Curriculum License ( Überblick

2 Identifiers Syntax Unicode! Case-sensitive
Identifier = (letter | '_' | {letter | digit | '_'}. Unicode! Case-sensitive can be used to treat keywords as identifiers - if ... keyword ... identifier if May contain Unicode escape sequences (e.g. \u03c0 for p) Examples someName sum_of3 _10percent @while the identifier while p the identifier p \u03c0 the identifier p b\u0061ck the identifier back Überblick

3 Keywords 77 keywords in C# in contrast to 47 keywords in Java
abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void volatile while 77 keywords in C# in contrast to 47 keywords in Java Überblick

4 Naming Conventions Casing First word
Words are capitalized (z.B. ShowDialog) First letter in upper case, except for private or local variables, constants and fields constants upper case SIZE, MAX_VALUE local variables lower case i, top, sum private fields lower case data, lastElement public fields upper case Width, BufferLength properties upper case Length, FullName enumeration constants upper case Red, Blue methods upper case Add, IndexOf types upper case StringBuilder (predefined types in lower case: int, string) namespaces upper case System, Collections First word Names of void methods should start with a verb (e.g. GetHashCode) Other names should start with a noun (e.g. size, IndexOf, Collections) Enumeration constants or bool members may start with an adjective (Red, Empty) Überblick

5 Integer Numbers Syntax Type
DecConstant = digit {digit} {IntSuffix}. HexConstant = "0x" hexDigit {hexDigit} {IntSuffix}. IntSuffix = 'u' | 'U' | 'l' | 'L'. Type without suffix: smallest type from int, uint, long, ulong suffix u, U: smallest type from uint, ulong suffix l, L: smallest type from long, ulong Examples 17 int long 17L long 17u uint 0x3f int 0x10000 long 0x3fL long Überblick

6 Floating-point Numbers
Syntax (simplified) RealConstant = [Digits] ["." [Digits]] [Exp] [RealSuffix]. must have at least 1 digit and either ".", Exp oder RealSuffix Digits = digit {digit}. Exp = ("e" | "E") ["+" | "-"] Digits. RealSuffix = "f" | "F" | "d" | "D" | "m" | "M". Type without suffix: double suffix f, F: float suffix d, D: double suffix m, M: decimal Examples 3.14 double 1E-2 double .1 double 10f float Überblick

7 Character Constants and Strings
Syntax CharConstant = ' char '. StringConstant = " {char} ". char can be Any character except closing quote, end-of-line or \ Escape sequences \' ' \" " \\ \ \0 0x0000 \a 0x0007 (alert) \b 0x0008 (backspace) \f 0x000c (form feed) \n 0x000a (new line) \r 0x000d (carriage return) \t 0x0009 (horizontal tab) \v 0x000b (vertical tab) Unicode- or hexadecimal escape sequences \u0061 a \x0061 a Überblick

8 Character Constants and Strings (cont.)
Examples for escape sequences in strings "file \"C:\\sample.txt\"" file "C:\sample.txt" "file \x0022C:\u005csample.txt\x0022" If the string is preceded by the \ is not interpreted as a escape character any " must be doubled the string may span several lines Example @"file file ""C:\sample.txt""" "C:\sample.txt" Überblick

9 Comments Single-line comments Delimited comments
// a comment Delimited comments /* a comment */ must not be nested Documentation comments /// a documentation comment Überblick

10 Uniform Type System Types Value Types Reference Types Pointers
Simple Types Enums Structs Classes Interfaces Arrays Delegates bool char sbyte short int long byte ushort uint ulong float double decimal User-defined Types blue types are missing from Java All types are compatible with object (System.Object) - can be assigned to variables of type object - all operations of type object are applicable to them Überblick

11 Value Types and Reference Types
Value Types Reference Types variable contains value reference stored on stack heap initialization 0, false, '\0' null assignment copies the value copies the reference example int i = 17; string s = "Hello"; int j = i; string s1 = s; i 17 s H e l l o j 17 s1 Überblick

12 Primitive Types long name in Java range
sbyte System.SByte byte byte System.Byte short System.Int16 short ushort System.UInt int System.Int32 int uint System.UInt long System.Int64 long ulong System.UInt float System.Single float 1.5E 3.4E38 (32 Bit) double System.Double double 5E 1.7E308 (64 Bit) decimal System.Decimal --- 1E 7.9E28 (128 Bit) bool System.Boolean boolean true, false char System.Char char Unicode character Überblick

13 Compatibility Between Primitive Types
decimal double float long int short sbyte ulong uint ushort byte only with type cast char The following assignments are legal intVar = shortVar; intVar = charVar; floatVar = charVar; decimalVar = (decimal)doubleVar; Überblick

14 Contents of Classes and Structs
class C { ... fields, constants // for object-oriented programming ... methods ... ... constructors, destructors ... ... properties ... // for component-based programming ... events ... ... indexers ... // for amenity ... overloaded operators ... ... nested types (classes, interfaces, structs, enums, delegates) ... } Überblick

15 Classes class Stack { int[] values; int top = 0; public Stack(int size) { ... } public void Push (int x) {...} public int Pop() {...} } Objects are allocated on the heap (classes are reference types) Objects must be created with new Stack s = new Stack(100); Classes can inherit from one other class (single code inheritance) Classes can implement multiple interfaces (multiple type inheritance) Überblick

16 Class System.Object Base class of all reference types
class Object { public virtual bool Equals(object o) {...} public virtual string ToString() {...} public virtual int GetHashCode() {...} ... } Can be used as the standard type object object obj; // compiler maps object to System.Object Assignment compatibility obj = new Rectangle(); obj = new int[3]; Affords methods that work on arbitrary objects void Push(object x) {...} Push(new Rectangle()); Push(new int[3]); Überblick

17 Class System.String Can be used as the standard type string Note
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, ... Überblick

18 Arrays One-dimensional arrays Multidimensional arrays (jagged)
int[] a = new int[3]; int[] b = new int[] {3, 4, 5}; int[] c = {3, 4, 5}; SomeClass[] d = new SomeClass[10]; // array of references SomeStruct[] e = new SomeStruct[10]; // array of values (directly in the array) Multidimensional arrays (jagged) int[][] a = new int[2][]; // array of references to other arrays a[0] = new int[] {1, 2, 3}; // cannot be initialized directly a[1] = new int[] {4, 5, 6}; Multidimensional arrays (rectangular) int[,] a = new int[2, 3]; // block matrix int[,] b = {{1, 2, 3}, {4, 5, 6}}; // can be initialized directly int[,,] c = new int[2, 4, 2]; Überblick

19 Multidimensional Arrays
Jagged (like in Java) a[0][1] a int[][] a = new int[2][]; a[0] = new int[3]; a[1] = new int[4]; int x = a[0][1]; a[0] a[1] Rectangular (more compact and efficient) int[,] a = new int[2, 3]; int x = a[0, 1]; a[0, 1] a Überblick

20 Other Array Properties
Indexes start at 0 Array length int[] a = new int[3]; Console.WriteLine(a.Length); // 3 int[][] b = new int[3][]; b[0] = new int[4]; Console.WriteLine("{0}, {1}", b.Length, b[0].Length); // 3, 4 int[,] c = new int[3, 4]; Console.WriteLine(c.Length); // 12 Console.WriteLine("{0}, {1}", c.GetLength(0), c.GetLength(1)); // 3, 4 System.Array provides some useful array operations int[] a = {7, 2, 5}; int[] b = new int[2]; Array.Copy(a, b, 2); // copies a[0..1] to b Array.Sort(b); ... Überblick

21 Structs struct Point { int x, y; public Point(int x, int y) { this.x = x; this.y = y; } public void 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(); Fields must not be initialized at their declaration int x = 0; // compilation error Parameterless construcors cannot be declared Can neither inherit nor be inherited, but can implement interfaces Überblick

22 Differences Between Classes and Structs
Reference types (objects are allocated on the heap) support inheritance (all classes are derived from object) can implement interfaces may declare a parameterless constructor may have a destructor Structs Value types (objects are allocated on the stack) no inheritance (but they are compatible with object) can implement interfaces must not declare a parameterless constructor no destructors Überblick

23 Boxing and Unboxing Value types (int, struct, enum) are compatible with object! Boxing The assignment object obj = 3; wraps up the value 3 in a heap object Unboxing int x = (int) obj; unwraps the value again obj 3 Überblick

24 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); Rectangle r = (Rectangle) q.Dequeue(); int x = (int) q.Dequeue(); But there is also true genericity (see later) Überblick

25 Structure of C# Programs
Programm File1.cs File2.cs File3.cs namespace A {...} namespace B {...} namespace C {...} class X {...} class Y {...} class Z {...} If no namespace is specified => anonymous default namespace Namespaces may also contain structs, interfaces, delegates and enums Namespace may be "reopened" in other files Simplest case: single class, single file, default namespace Überblick

26 Namespaces A file can declare multiple namespaces.
File: XXX.cs File: YYY.cs A file can declare multiple namespaces. A namespace can be re-opened in another file. Types that are not declared in any namespace, are considered to be in a default namespace (global namespace). namespace A { ... } namespace B { // full name: A.B ... } File: ZZZ.cs namespace A { ... } namespace A.B { ... } namespace B {...} namespace C {...} Überblick

27 Using Other Namespaces
Color.cs Figures.cs Triangle.cs namespace Util { enum Color {...} } namespace Util.Figures { class Rect {...} class Circle {...} } namespace Util.Figures { class Triangle {...} } 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) Überblick

28 C# Namespaces vs. Java Packages
A file may contain multiple namespaces A file may contain just 1 package xxx.cs xxx.java namespace A {...} namespace B {...} namespace C {...} package A; ... Namespaces and classes are not mapped to directories and files Packages and classes are mapped to directories and files namespace A { class C {...} } xxx.cs package A; C.java Samples A Überblick

29 Namespaces vs. Packages (continued)
Java Imports namespaces Imports classes using System; import java.util.LinkedList; import java.awt.*; Namespaces are imported in other namesp. Classes are imported in files namespace A { using C; // imports C into A } // only in this file namespace B { using D; } import java.util.LinkedList; Alias names allowed using F = System.Windows.Forms; ... F.Button b; for explicit qualification and short names Java has visibility package package A; class C { void f() {...} // package } C# has only visibility internal (!= namespace) Überblick

30 Assemblies Run time unit consisting of types and other resources (e.g. icons) An assembly is a - Unit of deployment: assembly is smallest unit that can be deployed individually - Unit of versioning: all types in an assembly have the same version number Often: 1 assembly = 1 namespace = 1 program But: - one assembly may consist of multiple namespaces - one namespace may be spread over several assemblies - an assembly may consist of multiple files, held together by a manifest ("table of contents") Assembly  JAR file in Java Assembly  Component in .NET namespace A C1 C2 namespace B C3 C4 icon assembly Manifest Metadata class A class B struct C Überblick

31 Hello World Program File Hello.cs using System;
class Hello { static void Main() { Console.WriteLine("Hello World"); } imports the namespace System entry point must be called Main prints to the console file name and class name need not be identical. Compilation (from the Console window; produces Hello.exe) csc Hello.cs Execution Hello Überblick

32 Output to the Console Placeholder syntax Examples
Console.Write(intVal); // overloaded for all primitive types Console.WriteLine(intVal); // for objects ToString() is called automatically Console.Write("Hello {0}", name); // placeholder Console.WriteLine("{0} = {1}", x, y); Placeholder syntax "{" n ["," width] [":" format [precision]] "}" n argument number (starting at 0) width field width (exceeded if too small) positive = right-aligned, negative = left-aligned format formatting code (e.g. d, f, e, x, ...) precision number of fractional digits (sometimes number of digits) Example: {0,10:f2} Überblick

33 Formatting Codes for Numbers
d, D decimal format (integer number with leading zeroes) -xxxxx precision = number of digits f, F fixed-point format -xxxxx.xx precision = number of fractional digits (default = 2) n, N number format (with separator for thousands) -xx,xxx.xx e, E floating-point format (case is significant) -x.xxxE+xxx precision = number of fractional digits c, C currency format $xx,xxx.xx negative values are enclosed in brackets ($xx,xxx.xx) x, X hexadecimal format (case is significant) xxx precision = number of hex digits (maybe leading 0) g, G general (most compact format for the given value; default) Überblick

34 Examples int x = 17; Console.WriteLine("{0}", x); 17
Console.WriteLine("{0:d}", x); 17 Console.WriteLine("{0:d5}", x); 00017 Console.WriteLine("{0:f}", x); 17.00 Console.WriteLine("{0:f1}", x); 17.0 Console.WriteLine("{0:E}", x); E+001 Console.WriteLine("{0:E1}", x); 1.7E+001 Console.WriteLine("{0:x}", x); 11 Console.WriteLine("{0:x4}", x); 0011 Überblick

35 String Formatting With ToString for numeric types (int, long, short, ...): string s; int i = 12; s = i.ToString(); // "12" s = i.ToString("x4"); // "000c" s = i.ToString("f"); // "12.00" With String.Format for arbitrary types s = String.Format("{0} = {1,6:x4}", name, i); // "val = 000c" Culture-specific formatting s = i.ToString("c"); // "$12.00" s = i.ToString("c", new CultureInfo("en-GB")); // "£12.00" s = i.ToString("c", new CultureInfo(“cs-CZ")); // "12,00 Kč" Überblick

36 Formatted Output to a File
using System; using System.IO; class Test { static void Main() { FileStream s = new FileStream("output.txt", FileMode.Create); StreamWriter w = new StreamWriter(s); w.WriteLine("Table of sqares:"); for (int i = 0; i < 10; i++) w.WriteLine("{0,3}: {1,5}", i, i*i); w.Close(); } It is not possible to have multiple StreamWriters working on the same stream at the same time. Überblick

37 Keyboard Input int ch = Console.Read(); returns the next character. waits until the user pressed the return key. e.g. input: "abc" + return key. Read returns: 'a', 'b', 'c', '\r', '\n'. after the last character (Ctrl-Z + return) Read returns -1 string line = Console.ReadLine(); returns the next line (after Ctrl-Z+CR+LF it returns null). waits until the user pressed the return key. returns the line without CR, LF. Überblick

38 Input from a File using System; using System.IO; class Test { static void Main() { FileStream s = new FileStream("input.txt", FileMode.Open); StreamReader r = new StreamReader(s); string line = r.ReadLine(); while (line != null) { ... line = r.ReadLine(); } r.Close(); It is not possible to have multiple StreamReaders working on the same stream at the same time. Überblick

39 Reading Command-line Parameters
using System; class Test { static void Main(string[] arg) { // e.g. invoked as: Test value = 3 for (int i = 0; i < arg.Length; i++) Console.WriteLine("{0}: {1}", i, arg[i]); // output (tokens are separated by blanks): // 0: value // 1: = // 2: 3 foreach (string s in arg) Console.WriteLine(s); // output: // value // = // 3 } Überblick

40 Visibility Visibility modifiers: public Access is not restricted.
protected Access is limited to the containing class or types derived from the containing class. internal Access is limited to the current assembly. protected internal Access is limited to the current assembly or types derived from the containing class. private Access is limited to the containing type. Default visibility in: enum public class private interface public struct private Überblick

41 Access to private Members
class B { private int x; ... } class C { public void f (C c) { x = ...; // method may access private members of this. c.x = ...; // method of class C may access private members // of some other C object. B b = ...; b.x = ...; // error! method of class C must not access private members // of some other class. Überblick

42 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 = += -= *= /= %= <<= >>= &= ^= |= Operators on the same level are evaluated from left to right. The unary operators +, -, ~, ! as well as type casts are evaluated from right to left: - (int) x  - ((int) x) Überblick

43 Arithmetic Expressions
Operand types must be - numeric or char - operands of ++ and -- must be numeric or enumeration constants (++ and -- work also on float and double!) Result type Smallest numeric type that includes both operand types, but at least int. Note - uint => long - ulong => illegal uint  (sbyte | short | int) => long ulong  (sbyte | short | int | long) => illegal decimal  (float | double) => illegal byte  (byte) => int char  (char) => int Überblick

44 Comparisons Operand types Result type
- <, >, <=, >=: numeric, char, enum - ==, !=: numeric, char, enum, bool, reference types - x is T: x: expression of arbitrary type, T: reference type e.g.: obj is Rectangle objOfValueType is IComparable 3 is object arr is int[] Result type bool Überblick

45 Boolean Expressions (&, |, &&, ||, !)
Operand types bool Result type Full evaluation a & b a | b Short evaluation (conditional evaluation) a && b => if (a) b else false a || b => if (a) true else b Useful in if (p != null && p.val > 0) ... if (x == 0 || y / x > 2) ... Überblick

46 Bit Expressions (&, |, ^, ~)
Operand types - & | ^ : integer type, char, enum - ~ : integer type, char, enum - if the operand types are not identical the operand with the smaller type is converted to the larger type prior to the operation Result type - largest of the two operand types - for numeric types and char the result type is at least int Überblick

47 Shift Expressions Operand types for x << y and x >> y
- x: integer type or char - y: int Result type type of x, but at least int Note - does a logical shift for unsigned types and an arithmetic shift for signed types Überblick

48 Overflow Checks Overflow is not checked by default
int x = ; x = x * x; // , no error Overflow checks can be turned on x = checked(x * x); //  System.OverflowException checked { ... x = x * x; //  System.OverflowException } Overflow checks can also be turned on with a compiler switch csc /checked Test.cs Überblick

49 Simple Statements Empty statement Assigment Method call
; // ; 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) s = String.Join(" + ", parts); // invocation of a class method (static) Überblick

50 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 " + ch); } Überblick

51 switch Statement Type of the switch expression
switch (country) { case "England": case "USA": language = "English"; break; case "Germany": case "Austria": case "Switzerland": language = "German"; case null: Console.WriteLine("no country specified"); default: Console.WriteLine("don't know the language of " + country); } Type of the switch expression integer type, char, enum or string (null ok as a case label). No fall-through (unlike in C or in Java)! Every statement sequence in a case must be terminated with break (or return, goto, throw). If no case label matches  default If no default specified  continuation after the switch statement Überblick

52 switch with Gotos E.g. for the implementation of automata
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; } case 2: Console.WriteLine("input valid"); break; default: Console.WriteLine("illegal character " + ch); } b a c 1 2 c Überblick

53 Loops while do while for short form for while (i < n) { sum += i;
++; } do while do { sum += a[i]; i--; } while (i > 0); for short form for for (int i = 0; i < n; i++) int i = 0; sum += i; while (i < n) { i++; Überblick

54 foreach Statement For iterating over collections and arrays
int[] a = {3, 17, 4, 8, 2, 29}; foreach (int x in a) sum += x; string s = "Hello"; foreach (char ch in s) Console.WriteLine(ch); Queue q = new Queue(); // elements are of type object q.Enqueue("John"); q.Enqueue("Alice"); ... foreach (string s in q) Console.WriteLine(s); Überblick

55 Jumps There is no break with a label like in Java (use goto instead).
break; For exiting a loop or a switch statement. There is no break with a label like in Java (use goto instead). continue; Continues with the next loop iteration. goto case 3: Can be used in a switch statement to jump to a case label. 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 Überblick

56 return Statement Returning from a void method
void Foo (int x) { if (x == 0) return; ... } Returning a value from a function method int Max (int a, int b) { if (a > b) return a; else return b; 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 // system variable errorlevel Überblick

57 Declaration Space The program area to which a declaration belongs
Kinds of declaration spaces - namespace: declarations of classes, interfaces, structs, enums, delegates - class, interface, struct: declaraions of fields, methods, ... - enumeration: declarations of enumeration constants - block: declarations of local variables namespace N { ... class C { void Foo() { if (...) { } Statement blocks are not declaration spaces on their own but belong to the declaration space of the enclosing method block Überblick

58 Statement Blocks Kinds of blocks
void foo (int x) { // method block ... local variables ... if (...) { // nested block } for (int i = 0; ...) { // nested block The declaration space of a block includes the declaration spaces of its nested blocks. Formal parameters belong to the declaration space of their method block. The loop variable of a for statement belongs to the block of this for statement. The declaration of a local variable must precede the use of this variable. B1 B2 B3 B1 B1 B2 B3 Überblick

59 Declaration of Local Variables
void foo(int a) { int b; if (...) { int b; // error: b is already declared in the outer block int c; int d; ... } else { int a; // error: a is already declared in the outer block (parameter) int d; // ok: no conflict with d in the if block } for (int i = 0; ...) {...} for (int i = 0; ...) {...} // ok: no conflict with i from the previous loop int c; // error: c is already declared in a nested block int e = 1, f; if (e == 1) { f = 2; e = f; // error: f is not initialized in every possible execution path Überblick

60 Fields and Constants Access within C Access from other classes
class C { int value = 0; Field - initialization is optional - initialization value must be computable at compile time - fields of a struct must not be initialized const long size = ((long)int.MaxValue + 1) / 4; Constant - must be initialized - value must be computable at compile time readonly DateTime date; Read-only field - must be initialized in their declaration or in a constructor - value needs not be computable at compile time - value must not be changed later - consumes a memory location (like a field) } Access within C Access from other classes ... value ... size ... date C c = new C(); ... c.value ... c.size ... c.date ... Überblick

61 Static Fields and Constants
Belong to a class, not to an object class Rectangle { static Color defaultColor; // once per class static readonly int scale; // -- " -- int x, y, width,height; // once per object ... } Access within the class Access from other classes ... defaultColor ... scale Rectangle.defaultColor ... Rectangle.scale ... Constants must not be declared static Überblick

62 Methods Example Access from class C Access from other classes
int sum = 0, n = 0; public void Add (int x) { // procedure sum = sum + x; n++; } public float Mean() { // function (must return a value) return (float)sum / n; Access from class C Access from other classes Add(3); C c = new C(); float x = Mean(); c.Add(3); float x = c.Mean(); Überblick

63 Static Methods Operations on class data (static fields)
class Rectangle { static Color defaultColor; public static void ResetColor() { defaultColor = Color.white; } Access from Rectangle Access from other classes ResetColor(); Rectangle.ResetColor(); Überblick

64 Parameters value parameters (input parameters)
void Inc(int x) {x = x + 1;} void f() { int val = 3; Inc(val); // val == 3 } - "call by value" - formal parameter is a copy of the actual parameter - actual parameter is an expression - "call by reference" - formal parameter is an alias for the actual parameter (address of actual parameter is passed) - actual parameter must be a variable ref parameters (transient parameters) void Inc(ref int x) { x = x + 1; } void f() { int val = 3; Inc(ref val); // val == 4 } - similar to ref parameters but no value is passed by the caller. - must not be used in the method before it got a value. out parameters (output parameters) void Read (out int first, out int next) { first = Console.Read(); next = Console.Read(); } void f() { int first, next; Read(out first, out next); Überblick

65 Variable Number of Parameters
Last n parameters may be a sequence of values of a certain type. void Add (out int sum, params int[] val) { sum = 0; foreach (int i in val) sum = sum + i; } params cannot be used for ref and out parameters Usage Add(out sum, 3, 5, 2, 9); // sum == 19 keyword params array type Another example void Console.WriteLine (string format, params object[] arg) {...} Überblick

66 Method Overloading Methods of a class may have the same name Examples
- 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); // ambiguous between F(int x, long y) and F(long x, int y); => compilation error F(i, i); // ambiguous between 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! Überblick

67 Method Overloading Overloaded methods must not differ only in their function types int F() {...} string F() {...} F(); // if the return value is ignored, the name F cannot be resolved The following overloading is illegal as well void P(int[] a) {...} void P(params int[] a) {...} int[] a = {1, 2, 3}; P(a); // should call P(int[] a) P(1, 2, 3); // should call P(params int[] a) Reason for this restriction lies in the implementation of the: The CIL does not contain the address of the called method but a description of it, which is identical for both cases. Überblick

68 Constructors for Classes
Example class Rectangle { int x, y, width, height; public int dummy; 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) {} } Rectangle r1 = new Rectangle(); Rectangle r2 = new Rectangle(2, 5); Rectangle r3 = new Rectangle(2, 2, 10, 5); int i = r1.dummy; // OK – r1.dummy is initialized to 0 Constructors can be overloaded. A constructor may call another constructor with this (specified in the constructor head, not in its body as in Java!). Before a constructor is called, fields are possibly initialized. Überblick

69 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 default constructor initializes all fields as follows: numeric 0 enumeration 0 bool false char '\0' reference null If a constructor was declared, no default constructor is generated : class C { int x; public C(int y) { x = y; } } C c1 = new C(); // compilation error C c2 = new C(3); // ok Überblick

70 Constructor 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) {} ... } Complex c0; // c0.re and c0.im uninitialized Complex c1 = new Complex(); // c1.re == 0, c1.im == 0 Complex c2 = new Complex(5); // c2.re == 5, c2.im == 0 Complex c3 = new Complex(10, 3); // c3.re == 10, c3.im == 3 For every struct the compiler generates a parameterless default constructor (even if there are other constructors). The default constructor zeroes all fields. Programmers must not declare a parameterless constructor for structs A constructor of a struct must initialize all fields. Überblick

71 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. Used for initialization of static fields. Überblick

72 Destructors Correspond to finalizers in Java.
class Test { ~Test() { ... cleanup actions ... } Correspond to finalizers in Java. Called for an object before it is removed by the garbage collector. Can be used, for example, to close open files. Base class destructor is called automatically at the end. No public or private. Is dangerous (object resurrection) and should be avoided Structs must not have a destructor (reason unknown). Überblick

73 Properties Syntactic sugar for get/set methods Used as "smart fields"
class Data { FileStream s; public string FileName { set { s = new FileStream(value, FileMode.Create); } get { return s.Name; Used as "smart fields" Data d = new Data(); d.FileName = "myFile.txt"; // calls set("myFile.txt") string s = d.FileName; // calls get() JIT compilers often inline get/set methods  no efficiency penalty. property type property name "input parameter" of the set method Überblick

74 Properties (continued)
Assignment operators work also on properties class C { private static int size; public static int Size { get { return size; } set { size = value; } } C.Size = 3; C.Size += 2; // Size = Size + 2; Überblick

75 Properties (continued)
get or set can be omitted class Account { long balance; public long Balance { get { return balance; } } x = account.Balance; // ok account.Balance = ...; // illegal Why are properties a good idea? Allow read-only and write-only fields. Can validate a field when it is accessed. Interface and implementation of data can differ. Substitute for fields in interfaces. Überblick

76 Indexers Programmable operator for indexing a collection Usage
class File { FileStream s; public int this [int index] { get { s.Seek(index, SeekOrigin.Begin); return s.ReadByte(); } set { s.Seek(index, SeekOrigin.Begin); s.WriteByte((byte)value); Usage File f = ...; int x = f[10]; // calls f.get(10) f[10] = 'A'; // calls f.set(10, 'A') get or set method can be omitted (write-only / read-only) indexers can be overloaded with different index type .NET library has indexers for string (s[i]), ArrayList (a[i]), etc. type of the indexed expression name (always this) type and name of the index value Überblick

77 Indexers (other example)
class MonthlySales { int[] apples = new int[12]; int[] bananas = new int[12]; ... public int this[int i] { // set method omitted => read-only get { return apples[i-1] + bananas[i-1]; } } public int this[string month] { // overloaded read-only indexer get { switch (month) { case "Jan": return apples[0] + bananas[0]; case "Feb": return apples[1] + bananas[1]; MonthlySales sales = new MonthlySales(); Console.WriteLine(sales[1] + sales["Feb"]); Überblick

78 Operator Overloading Static method for implementing a certain operator
struct Fraction { int x, y; public Fraction (int x, int y) {this.x = x; this.y = y; } public static Fraction operator + (Fraction a, Fraction b) { return new Fraction(a.x * b.y + b.x * a.y, a.y * b.y); } Usage Fraction a = new Fraction(1, 2); Fraction b = new Fraction(3, 4); Fraction c = a + b; // c.x == 10, c.y == 8 The following operators can be overloaded: arithmetic: +, - (unary and binary), *, /, %, ++, -- relational: ==, !=, <, >, <=, >= bit operators: &, |, ^ others: !, ~, >>, <<, true, false Must always return a function result If == (<, <=, true) is overloaded,!= (>=, >, false) must be overloaded as well. Überblick

79 Overloading of && and ||
In order to overload && and ||, one must overload &, |, true and false class TriState { int state; // -1 == false, +1 == true, 0 == undecided public TriState(int s) { state = s; } public static bool operator true (TriState x) { return x.state > 0; } public static bool operator false (TriState x) { return x.state < 0; } public static TriState operator & (TriState x, TriState y) { if (x.state > 0 && y.state > 0) return new TriState(1); else if (x.state < 0 || y.state < 0) return new TriState(-1); else return new TriState(0); } public static TriState operator | (TriState x, TriState y) { if (x.state > 0 || y.state > 0) return new TriState(1); else if (x.state < 0 && y.state < 0) return new TriState(-1); true and false are called implicitly TriState x, y; if (x) => if (TriState.true(x)) ... x = x && y; => x = TriState.false(x) ? x : TriState.&(x, y); x = x || y; => x = TriState.true(x) ? x : TriState.|(x, y) Überblick

80 Conversion Operators Implicit conversion Explicit 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; Conversion operators for user-defined types class Fraction { int x, y; ... public static implicit operator Fraction (int x) { return new Fraction(x, 1); } public static explicit operator int (Fraction f) { return f.x / f.y; } } Usage Fraction f = 3; // implicit conversion, f.x == 3, f.y == 1 int i = (int) f; // explicit conversion, i == 3 Überblick

81 Special Operator Methods
Operators, indexers, properties and events are compiled into “normal” methods - get_* (property getter) - set_* (property setter) - get_Item (indexer getter) - set_Item (indexer setter) - add_* (event handler addition) - remove_* (event handler removal) - op_Addition (binary +) - op_Subtraction (binary -) - op_Implicit (implicit cast) - op_Explicit (explicit cast) etc. Überblick

82 Nested Types For auxiliary classes that should be hidden
class A { private int x; B b; public void Foo() { b.Bar(); } ... } class C { A a = new A(); A.B b = new A.B(); For auxiliary classes that should be hidden - Inner class can access all members of the outer class (even private members). - Outer class can access only public members of the inner class. - Other classes can access an inner class only if it is public. Nested types can also be structs, enums, interfaces and delegates. public class B { A a; public void Bar() { a.x = ...; ... a.Foo(); } ... } Überblick

83 Differences to Java No anonymous types like in Java
Different default visibility for members C#: private Java: package Different default visibility for types C#: internal Java: package Überblick

84 Inheritance – Syntax B inherits a and F(), it adds b and G()
class A { // base class int a; public A() {...} public void F() {...} } class B : A { // subclass (inherits from A, extends A) int b; public B() {...} public void G() {...} B inherits a and F(), it adds b and G() - constructors are not inherited - inherited methods can be overridden (see later) Single inheritance: a class can only inherit from one base class, but it can implement multiple interfaces. A class can only inherit from a class, not from a struct. Structs cannot inherit from another type, but they can implement multiple interfaces. A class without explicit base class inherits from object. Überblick

85 Assignments and Type Checks
class A {...} class B : A {...} class C: B {...} Assignments A a = new A(); // static type of a: the type specified in the declaration (here A) // dynamic type of a: the type of the object in a (here also A) a = new B(); // dynamic type of a is B a = new C(); // dynamic type of a is C B b = a; // forbidden; compilation error Run-time type checks a = new C(); if (a is C) ... // true, if the dynamic type of a is C or a subclass; otherwise false if (a is B) ... // true if (a is A) ... // true, but warning because it makes no sense a = null; if (a is C) ... // false: if a == null, a is T always returns false Überblick

86 Checked Type Casts Cast as A reala = new A(); A a = new C();
B b = (B) a; // if (a is B) stat.type(a) is B in this expression; else exception C c = (C) a; a = null; c = (C) a; // ok  null can be casted to any reference type C cc = (C) reala; // runtime error  InvalidCastException as A a = new C(); A reala = new A(); B b = a as B; // if (a is B) b = (B)a; else b = null; C c = a as C; a = null; c = a as C; // c == null C cc = reala as C; // ok  cc == null

87 Overriding Methods Only methods that are declared as virtual can be overridden in subclasses class A { public void F() {...} // cannot be overridden public virtual void G() {...} // can be overridden in a subclass } Overriding methods must be declared as override class B : A { public void F() {...} // warning: hides inherited F()  use new public void G() {...} // warning: hides inherited G()  use new public override void G() { // ok: overrides inherited G ... base.G(); // calls inherited G() Method signatures must be identical - same number and types of parameters (including function type) - same visibility (public, protected, ...). Properties and indexers can also be overridden (virtual, override). Static methods cannot be overridden.

88 Dynamic Binding class A { public virtual void WhoAreYou() { Console.WriteLine("I am an A"); } } class B : A { public override void WhoAreYou() { Console.WriteLine("I am a B"); } A message invokes the method belonging to the dynamic type of the receiver (not quite true, see later) A a = new B(); a.WhoAreYou(); // "I am a B" Benefit: every method that can work with A can also work with B void Use (A x) { x.WhoAreYou(); Use(new A()); // "I am an A" Use(new B()); // "I am a B"

89 Hiding Members can be declared as new in a subclass.
They hide inherited members with the same name and signature. class A { public int x; public void F() {...} public virtual void G() {...} } class B : A { public new int x; public new void F() {...} public new void G() {...} B b = new B(); b.x = ...; // accesses B.x b.F(); ... b.G(); // calls B.F and B.G ((A)b).x = ...; // accesses A.x! ((A)b).F(); ... ((A)b).G(); // calls A.F and A.G!

90 A More Complex Example class Animal {
public virtual void WhoAreYou() { Console.WriteLine("I am an animal"); } } class Dog : Animal { public override void WhoAreYou() { Console.WriteLine("I am a dog"); } class Beagle : Dog { public new virtual void WhoAreYou() { Console.WriteLine("I am a beagle"); } class AmericanBeagle : Beagle { public override void WhoAreYou() { Console.WriteLine("I am an american beagle"); } Beagle pet = new AmericanBeagle(); pet.WhoAreYou(); // "I am an american beagle" Animal pet = new AmericanBeagle(); pet.WhoAreYou(); // "I am a dog" !!

91 Fragile Base Class Problem
Initial situation class LibraryClass { public void CleanUp() { ... } } class MyClass : LibraryClass { public void Delete() { ... erase the hard disk ... } Later: vendor ships new version of LibraryClass class LibraryClass { string name; public virtual void Delete() { name = null; ... } public void CleanUp() { Delete(); ... } } In Java the call myObj.CleanUp() would erase the hard disk! class MyClass : LibraryClass { public void Delete() { ... erase the hard disk ... } In C# nothing happens, as long as MyClass is not recompiled. MyClass still relies on the old version of LibraryClass (Versioning)  old CleanUp() does not call LibraryClass.Delete(). If MyClass is recompiled, the compiler forces Delete to be declared as new or override.

92 Constructors and Inheritance
Implicit call of the base class constructor Explicit call class A { ... } class B : A { public B(int x) {...} class A { public A() {...} } class B : A { public B(int x) {...} class A { public A(int x) {...} } class B : A { public B(int x) {...} class A { public A(int x) {...} } class B : A { public B(int x) : base(x) {...} B b = new B(3); B b = new B(3); B b = new B(3); B b = new B(3); OK - Default-constr. A() - B(int x) OK - A() - B(int x) Error! - no explicit call of the A() constructor - default constr. A() does not exist OK - A(int x) - B(int x)

93 Abstract Classes Example Note
abstract class Stream { public abstract void Write(char ch); public void WriteString(string s) { foreach (char ch in s) Write(s); } } class File : Stream { public override void Write(char ch) {... write ch to disk ...} Note Abstract methods do not have an implementation. Abstract methods are implicitly virtual. If a class has abstract methods (declared or inherited) it must be abstract itself. One cannot create objects of an abstract class..

94 Abstract Properties and Indexers
Example abstract class Sequence { public abstract void Add(object x); // method public abstract string Name { get; } // property public abstract object this [int i] { get; set; } // indexer } class List : Sequence { public override void Add(object x) {...} public override string Name { get {...} } public override object this [int i] { get {...} set {...} } Note Overridden indexers and properties must have the same get and set methods as in the base class

95 Sealed Classes Example Note
sealed class Account : Asset { long val; public void Deposit (long x) { ... } public void Withdraw (long x) { ... } ... } Note sealed classes cannot be extended (same as final classes in Java), but they can inherit from other classes. override methods can be declared as sealed individually. Reason: Security (avoids inadvertent modification of the class semantics) Efficiency (methods can possibly be called using static binding)

96 Class System.Object Topmost base class of all other classes
class Object { protected object MemberwiseClone() {...} public Type GetType() {...} public virtual bool Equals (object o) {...} public virtual string ToString() {...} public virtual int GetHashCode() {...} public static bool ReferenceEquals(object objA, object objB); } Directly usable: Type t = x.GetType(); returns a type descriptor (for reflection) object copy = x.MemberwiseClone(); does a shallow copy (this method is protected!) Overridable in subclasses: x.Equals(y) should compare the values of x and y x.ToString() should return a string representation of x int code = x.GetHashCode(); should return a hash code for x

97 Example (for using object)
class Fraction { int x, y; public Fraction(int x, int y) { this.x = x; this.y = y; } ... public override string ToString() { return String.Format("{0}/{1}", x, y); } public override bool Equals(object o) { Fraction f = (Fraction)o; return f.x == x && f.y == y; } public override int GetHashCode() { return x ^ y; } public Fraction ShallowCopy() { return (Fraction) MemberwiseClone(); } } class Client { static void Main() { Fraction a = new Fraction(1, 2); Fraction b = new Fraction(1, 2); Fraction c = new Fraction(3, 4); Console.WriteLine(a.ToString()); // 1/2 Console.WriteLine(a); // 1/2 (ToString is called automatically) Console.WriteLine(a.Equals(b)); // true Console.WriteLine(a == b); // false Console.WriteLine(a.GetHashCode()); // 3 a = c.ShallowCopy(); Console.WriteLine(a); // 3/4

98 Example (for overloading == and !=)
class Fraction { int x, y; public Fraction(int x, int y) { this.x = x; this.y = y; } ... public static bool operator == (Fraction a, Fraction b) { return a.x == b.x && a.y == b.y; } public static bool operator != (Fraction a, Fraction b) { return ! (a == b); } } class Client { static void Main() { Fraction a = new Fraction(1, 2); Fraction b = new Fraction(1, 2); Fraction c = new Fraction(3, 4); Console.WriteLine(a == b); // true Console.WriteLine((object)a == (object)b); // false Console.WriteLine(Object.ReferenceEquals(a, b)); // false Console.WriteLine(a.Equals(b)); // true, because overridden in Fraction If == is overloaded,!= must be overloaded as well. Compiler prints a warning if == and != are overloaded, but Equals is not overridden.

99 Interfaces – Syntax public interface IList : ICollection, IEnumerable { int Add (object value); // methods bool Contains (object value); ... bool IsReadOnly { get; } // property object this [int index] { get; set; } // indexer } Interface = purely abstract class; only signatures, no implementation. May contain methods, properties, indexers and events (no fields, constants, constructors, destructors, operators, nested types). Interface members are implicitly public abstract (virtual). Interface members must not be static. Classes and structs may implement multiple interfaces. Interfaces can extend other interfaces.

100 Implemented by Classes and Structs
class MyClass : MyBaseClass, IList, ISerializable { public int Add (object value) {...} public bool Contains (object value) {...} ... public bool IsReadOnly { get {...} } public object this [int index] { get {...} set {...} } } A class can inherit from a single base class, but can implement multiple interfaces. A struct cannot inherit from any type, but can implement multiple interfaces. Every interface member (method, property, indexer) must be implemented or inherited from a base class. Implemented interface methods must not be declared as override. Implemented interface methods can be declared as virtual or abstract (i.e. an interface can be implemented by an abstract class). If subclasses of MyClass should be able to override Add() it must be declared as virtual (although Add() is already implicitly virtual in IList).

101 Working with Interfaces
Assignments: MyClass c = new MyClass(); IList list = c; Method calls: list.Add("Tom"); // dynamic binding => MyClass.Add Type checks: if (list is MyClass) ... // true if (list is ISerializable) ... // true Type casts: c = list as MyClass; c = (MyClass) list; ISerializable ser = (ISerializable) list; <<interface>> <<interface>> MyBaseClass IList ISerializable MyClass

102 Example interface ISimpleReader { int Read(); }
interface IReader : ISimpleReader { void Open(string name); void Close(); class Terminal : ISimpleReader { public int Read() { ... } class File : IReader { public void Open(string name) { ... } public void Close() { ... } ISimpleReader sr = null; // null can be assigned to any variable of an interface type sr = new Terminal(); sr = new File(); IReader r = new File(); sr = r; <<interface>> ISimpleReader Read Terminal Read <<interface>> IReader Open Close File Read Open Close

103 Name Clashes Occurs if two base interfaces have methods with identical names interface I1 { void F(); } interface I2 { class B : I1, I2 { //----- implementation by a single F method public void F() { Console.WriteLine("B.F"); } //----- implementation by separate F methods void I1.F() { Console.WriteLine("I1.F"); } // must not be public void I2.F() { Console.WriteLine("I2.F"); } // must not be public B b = new B(); b.F(); // B.F I1 i1 = b; i1.F(); // I1.F I2 i2 = b; i2.F(); // I2.F

104 Delegate = Method Type Declaration of a delegate type
delegate void Notifier (string sender); // ordinary method signature // with the keyword delegate Declaration of a delegate variable Notifier greetings; Assigning a method to a delegate variable void SayHello(string sender) { Console.WriteLine("Hello from " + sender); } greetings = new Notifier(SayHello); Calling a delegate variable greetings("John"); // invokes SayHello("John") => "Hello from John"

105 Assigning Different Methods
Every matching method can be assigned to a delegate variable void SayGoodBye(string sender) { Console.WriteLine("Good bye from " + sender); } greetings = new Notifier(SayGoodBye); greetings("John"); // SayGoodBye("John") => "Good bye from John" Note A delegate variable can have the value null (no method assigned). If null, a delegate variable must not be called (otherwise exception). Delegate variables are first class objects: can be stored in a data structure, passed as a parameter, etc.

106 Creating a Delegate Value
new DelegateType (obj.Method) A delegate variable stores a method and its receiver, but no parameters ! new Notifier(myObj.SayHello); obj can be this (and can be omitted) new Notifier(SayHello); Method can be static. In this case the class name must be specified instead of obj. new Notifier(MyClass.StaticSayHello); Method must not be abstract, but it can be virtual, override, or new. Method signature must match the signature of DelegateType - same number of parameters - same parameter types (including the return type) - same parameter kinds (ref, out, value)

107 Multicast Delegates A delegate variable can hold multiple values at the same time Notifier greetings; greetings = new Notifier(SayHello); greetings += new Notifier(SayGoodBye); greetings("John"); // "Hello from John" // "Good bye from John" greetings -= new Notifier(SayHello); greetings("John"); // "Good bye from John" Note If the multicast delegate is a function, the value of the last call is returned If the multicast delegate has an out parameter, the parameter of the last call is returned. ref-Parameter are passed through all methods.

108 Event = Special Delegate Field
class Model { public event Notifier notifyViews; public void Change() { ... notifyViews("Model"); } } class View { public View(Model m) { m.notifyViews += new Notifier(Update); } void Update(string sender) { Console.WriteLine(sender + " was changed"); } class Test { static void Main() { Model model = new Model(); new View(model); new View(model); ... model.Change(); Why events instead of normal delegate variables? Only the class that declares the event can fire it (better encapsulation) Other classes may change event fields only with += or -= (but not with =)

109 Event Handling in the .NET Library
Delegates for event handling have the following signature delegate void SomeEvent (object source, MyEventArgs e); Result type: void 1. parameter: Sender of the event (type object) 2. parameter: event (subclass of System.EventArgs) public class EventArgs { public static readonly EventArgs Empty; }

110 Example public delegate void KeyEventHandler (object sender, KeyEventArgs e); public class KeyEventArgs : EventArgs { public virtual bool Alt { get {...} } // true if Alt key was pressed public virtual bool Shift { get {...} } // true if Shift key was pressed public bool Control { get {...} } // true if Ctrl key was pressed public bool Handled { get{...} set {...} } // indicates if event was already handled public int KeyValue { get {...} } // the typed keyboard code ... } class MyKeyEventSource { public event KeyEventHandler KeyDown; public KeyPressed() { KeyDown(this, new KeyEventArgs(...)); class MyKeyListener { public MyKeyListener(...) { keySource.KeyDown += new KeyEventHandler(HandleKey);} void HandleKey (object sender, KeyEventArgs e) {...}

111 Event Accessors Event subscription and unsubscription can be handled in client code - Similar to properties (add accessor is called during +=, remove accessor is called during -=) Both accessors needs to be declared Such event cannot be fired (does not have a delegate behind) public delegate void MyDelegate (); class A { private MyDelegate m_DelegateBehind; public event MyDelegate Event { add { m_DelegateBehind += value; } remove { m_DelegateBehind -= value;

112 Pointer Types Examples Syntax int int pointers to arbitrary types
ip int int* ip; // pointer to an int cell MyStruct* sp; // pointer to a MyStruct object void* vp; // pointer to any memory location int** ipp; // pointer to a pointer to an int cell sp MyStruct vp ipp int PointerType = UnmanagedType * | void *. UnmanagedType = ValueType | PointerType. pointers to arbitrary types if a struct type, all fields must be of an UnmanagedType Syntax pointers are not traced by the garbage collector (referenced objects are not collected) pointer types are not compatible with System.Object pointer variables can have the value null pointers of different types can be compared with each other (==, !=, <, <=, >, >=)

113 Unsafe Code Code that works with pointers is potentially unsafe
(can break type rules and destroy arbitrary memory locations) must be enclosed in an unsafe block or an unsafe method unsafe { int* p; ... } unsafe void foo() { int* p; ... } must be compiled with the unsafe option csc -unsafe MyProg.cs system administrator must assign FullTrust rights to the program

114 Using Pointers Dereferencing a pointer Access to struct fields
var int var; int* ip = &var; ip *ip = 5; int x = *ip; if v is of type T*, *v is of type T void* cannot be dereferenced Access to struct fields struct Block { int x, y, z; } Block b; Block* bp = &b; bp->x = 1; // pointer notation *(bp).y = 2 // alternatively bp x y z bp must be of type Block* works also for method calls b Access to array elements int[] a = new int[3]; int* ap = a; ap[0] = 1; // array notation *(ap+1) = 2 // alternatively ap no index bound checks! a 1 2

115 Address Arithmetic Pointers can be used in calculations
T* p = ...; p T T p++; p--; // increases p by size(T) p T* q, r; q = p + 2; r = p - 1; T p // q = p + 2*size(T) // r = p - size(T) r q No pointer arithmetic with void*

116 Type Casts On Pointers Implicit Casts Explicit Casts
int i; int* ip; Block* bp; void* vp; Implicit Casts (without cast operator) Explicit Casts (with cast operator) T1*  T2* ip = (int*)vp; vp = (void*)ip; bp = (Block*)vp; T*  intType ip = (int*)i; bp = (Block*)i; vp = (void*)i; i = (int)ip; i = (int)bp; i = (int)vp; T*  null ip = null; bp = null; vp = null; void*  T* vp = ip; vp = bp;

117 Pinned and Unpinned Variables
CANNOT be moved by the garbage collector local variables value parameters fields of structs which are pinned themselves Unpinned CAN be moved by the garbage collector fields of classes (also static fields) array elements ref and out parameters

118 Adress Operator Note yields the address of designator
designator must denote a pinned variable (e.g. &x, &s.f) the type of the variable must not be managed (i.e. no class, no array) if designator is of type T, &designator is of type T*

119 fixed Statement Pins an unpinned variable during this statement Syntax
(i.e. the garbage collector cannot move it during this statement) Syntax FixedStat = "fixed" "(" PointerType FixedVarDecl {"," FixedVarDecl} ")" Statement. FixedVarDecl = ident "=" ( "&" UnpinnedVar | ArrayVar | StringVar ). UnpinnedVar must be of an unmanaged type T T* must be assignable to PointerType array elements must be of an unmanaged type T T* must be asignable to PointerType char* must be assignable to PointerType Examples int field; int[] a = new int[10]; Person person = new Person(); string s = "Hello"; fixed (byte* p = &field) { Console.Write(*(p+1)); } fixed (int* p = &a[1]) {...} fixed (int* p = &person.id) {...} fixed (int* p = a) {...} fixed (char* p = s) {...} Variables that are declared in the header of a fixed statement are read-only

120 Examples Printing the bytes of an int variable String processing x
int x = 3; unsafe { byte* p = (byte*) &x; for (int i = 0; i < 4; i++) { Console.Write("{0:x2} ", *p); p++; } } 3 p String processing string s = "Hello"; unsafe { fixed (char* p = s) { for (int i = 0; p[i] != '\0'; i++) Console.Write(p[i]); } s H e l p o \0

121 Examples (continued) Overlaying a byte array with a struct type
struct Block { int x; float f; int y; } ... byte[] buffer = new byte[1024]; unsafe { fixed (byte* bp = &buffer[3]) { Block* b = (Block*) bp; Console.WriteLine(b->x + " " + b->f + " " + b->y); x f y buffer b

122 Dangers of Pointer Processing
Can destroy arbitrary memory locations int[] a = new int[3]; unsafe { fixed (int* p = a) { p[5] = 0; } } One can be left with pointers to objects that are moved by the garbage collector int[] a = new int[5]; int* p; unsafe { fixed (int* q = a) { p = a+2; } ... ... // GC can move array now *p = 5; // destroys data } p q a

123 Dangers of Pointer Processing (cont.)
One can be left with pointers to non-existing local variables static unsafe int* Foo() { int local = 3; return &local; } static unsafe void Main() { int* p = Foo(); ... *p = 5; // accesses non-existing local variable! Therefore Avoid pointer processing! Unless you really need it for system-level programming

124 try Statement catch clauses are checked in sequential order.
FileStream s = null; try { s = new FileStream(curName, FileMode.Open); ... } catch (FileNotFoundException e) { Console.WriteLine("file {0} not found", e.FileName); } catch (IOException) { Console.WriteLine("some IO exception occurred"); } catch { Console.WriteLine("some unknown error occurred"); } finally { if (s != null) s.Close(); } catch clauses are checked in sequential order. finally clause is always executed (if present). Exception parameter name can be omitted in a catch clause. Exception type must be derived from System.Exception. If exception parameter is missing, System.Exception is assumed.

125 System.Exception Properties Methods
e.Message the error message as a string; set by new Exception(msg); e.StackTrace trace of the method call stack as a string e.Source the application or object that threw the exception e.TargetSite the method object that threw the exception ... Methods e.ToString() returns the name of the exception and the StackTrace

126 Throwing an Exception By an invalid operation (implicit exception)
Division by 0 Index overflow Acess via a null reference ... By a throw statement (explicit exception) throw new FunnyException(10); class FunnyException : ApplicationException { public int errorCode; public FunnyException(int x) { errorCode = x; } } (By calling a method that throws an exception but does not catch it) s = new FileStream(...);

127 Exception Hierarchy (excerpt)
SystemException ArithmeticException DivideByZeroException OverflowException ... NullReferenceException IndexOutOfRangeException InvalidCastException ApplicationException ... user-defined exceptions IOException FileNotFoundException DirectoryNotFoundException WebException

128 Searching for a catch Clause
... F(); try { G(); .... } catch (Exc e) { ... } ... H(); .... ... throw new FooException(...); .... Caller chain is traversed backwards until a method with a matching catch clause is found. If none is found => Program is aborted with a stack trace Exceptions don't have to be caught in C# (in contrast to Java) No distinction between checked exceptions that have to be caught, and unchecked exceptions that don't have to be caught Advantage: convenient Disadvantage: less robust software

129 No throws Clause in Method Signature
Java void myMethod() throws IOException { ... throw new IOException(); ... } Callers of myMethod must either - catch IOException or - specify IOException in their own signature C# void myMethod() { Callers of myMethod may handle IOException or not. + convenient - less robust

130 Exceptions in Delegates
Delegates are treated as normal methods when searching for a catch clause. void A() { try { B(); } catch (...) { ... } void B() { myDelegate(); ... } void C() { try { D(); } catch (...) { ... } void D() { throw ...; ... } called as a delegate

131 Exceptions in Multicast Delegates
Main F G try { myDelegate(); } catch (Exc2) { ... } try { G(); } catch (Exc1) { ... } if (...) { throw new Exc1(); } else { throw new Exc2(); } H ... If Exc1 is thrown in G() it is caught in F() and then H() is called. If Exc2 is thrown in G() it is caught in Main() and H() is not called any more.

132 Attributes User-defined metainformation about program elements Example
Can be attached to types, members, assemblies, etc. Extend predefined attributes such as public, sealed or abstract. Are implemented as classes that are derived from System.Attribute. Are stored in the metadata of an assembly. Often used by CLR services (serialization, remoting, COM interoperability) Can be queried at run time. Example [Serializable] class C {...} // makes the class serializable Also possible to attach multiple attributes [Serializable] [Obsolete] class C {...} [Serializable, Obsolete]

133 Attributes with Parameters
name parameters come after pos. parameters positional parameter Example [Obsolete("Use class C1 instead", IsError=true)] // causes compiler message saying public class C {...} // that C is obsolete Positional parameter = parameter of the attribute's constructor Name parameter = a property of the attribute Attributes are declared as classes public class ObsoleteAttribute : Attribute { // class name ends with "Attribute" public string Message { get; } // but can be used as "Obsolete" public bool IsError { get; set; } public ObsoleteAttribute() {...} public ObsoleteAttribute(string msg) {...} public ObsoleteAttribute(string msg, bool error) {...} } values must be constants Valid variants: [Obsolete] // Message == "", IsError == false [Obsolete("some Message")] // IsError == false [Obsolete("some Message", false)] [Obsolete("some Message", IsError=false)]

134 Example: Conditional Attribute
Allows a conditional call of methods #define debug // preprocessor directive class C { [Conditional("debug")] // only possible for void methods static void Assert (bool ok, string errorMsg) { if (!ok) { Console.WriteString(errorMsg); System.Environment.Exit(0); } static void Main (string[] arg) { Assert(arg.Length > 0, "no arguments specified"); Assert(arg[0] == "...", "invalid argument"); ... Assert is only called, if debug was defined. Also useful for controlling trace output.

135 Example: AttributeUsage
AttributeUsage describes how user-defined attributes are to be used public class AttributeUsageAttribute : Attribute { public AttributeUsageAttribute (AttributeTargets validOn) {...} public bool AllowMultiple { get; set; } // default: false public bool Inherited { get; set; } // default: false } validOn to which program elements ist the attribute applicable? AllowMultiple can it be applied to the same program element multiple times? Inherited is it inherited by subclasses? Usage [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple=false)] public class MyAttribute : Attribute {...}

136 Defining Your Own Attributes
Declaration [AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface, Inherited=true)] class Comment : Attribute { string text, author; public string Text { get {return text;} } public string Author { get {return author;} set {author = value;} } public Comment (string text) { this.text = text; author ="HM"; } } Usage [Comment("This is a demo class for Attributes", Author="XX")] class C { ... } search should also be continued in subclasses Querying the attribute at runtime class Attributes { static void Main() { Type t = typeof(C); object[] a = t.GetCustomAttributes(typeof(Comment), true); Comment ca = (Comment)a[0]; Console.WriteLine(ca.Text + ", " + ca.Author); }

137 Calling a Windows DLL Function
Signature of the Win32 function int MessageBox (HWND hWnd, LPTSTR lpText, LPTSTR lpCaption, UINT uType); Invocation from C# using System; using System.Runtime.InteropServices; class Test { [DllImport("user32.dll")] static extern int MessageBox(int hWnd, string text, string caption, int type); // no body static void Main() { int res = MessageBox(0, "Isn't that cool?", "", 1); Console.WriteLine("res = " + res); }

138 DllImport Attribute [DllImport ( dll.name [, EntryPoint=function-name]
[, CharSet=charset-enum] // for string marshaling [, ExactSpelling= (true|false)] // should name be modified acc. to CharSet? [, SetLastError= (true|false)] // true: returns Win32 error info [, CallingConvention=callconv-enum] )] charset-enum: CharSet.Auto (default), CharSet.Ansi, CharSet.Unicode, ... callconv-enum: CallingConvention.StdCall (default), CallingConvention.FastCall, ...

139 Parameter Marshaling Primitive types of C# are automatically mapped to Win32 types. Standard mapping can be modified as follows: using System.Runtime.InteropServices; ... [DllImport("...")] static extern void Foo ( [MarshalAs(UnmanagedType.LPStr)] string s, int x ); ANSI string of bytes LPStr ANSI string consisting of bytes LPWStr Unicode string LPTStr default: Windows NT/2000 => Unicode, Windows 98 => ANSI

140 Passing Classes and Structs as Param.
using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] // members are allocated sequentially class Time { // and are packed public ushort year; public ushort month; ... } [StructLayout(LayoutKind.Explicit)] // members are allocated at the specified offsets struct S { [FieldOffset(0)] ushort x; [FieldOffset(2)] int y; [DllImport("...")] static extern void Foo(Time t); [DllImport("...")] static extern void Foo1([MarshalAs(UnmanagedType.LPStruct)] Time t); [DllImport("...")] static extern void Bar(S s); Foo(new Time()); Bar(new S());

141 StructLayout Attribute
[StructLayout ( layout-enum // Sequential | Explicit | Auto [, Pack=packing-size] // 0, 1, 2, 4, 8, 16, ... [, CharSet=charset-enum] // Ansi | Unicode | Auto )]

142 Special Comments (like javadoc)
Example /// ... comment ... class C { public int f; public void Foo() {...} } Compilation csc /doc:MyFile.xml MyFile.cs Checks if comments are complete and consistent e.g. if one parameter of a method is documented, all parameters must be documented; Names of program elements must be spelled correctly. Generates an XML file with the commented program elements XML can be formatted for the Web browser with XSL

143 Example of a Commented Source File
/// <summary> A counter for accumulating values and computing the mean value.</summary> class Counter { /// <summary>The accumulated values</summary> private int value; /// <summary>The number of added values</summary> public int n; /// <summary>Adds a value to the counter</summary> /// <param name="x">The value to be added</param> public void Add(int x) { value += x; n++; } /// <summary>Returns the mean value of all accumulated values</summary> /// <returns>The mean value, i.e. <see cref="value"/> / <see cref="n"/></returns> public float Mean() { return (float)value / n;

144 Generated XML File XML file can be viewed in HTML using Visual Studio.
<?xml version="1.0"?> <doc> <assembly> <name>MyFile</name> </assembly> <members> <member name="T:Counter"> <summary> A counter for accumulating values and computing the mean value.</summary> </member> <member name="F:Counter.value"> <summary>The accumulated values</summary> <member name="F:Counter.n"> <summary>The number of added values</summary> <member name="M:Counter.Add(System.Int32)"> <summary>Adds a value to the counter</summary> <param name="x">The value to be added</param> <member name="M:Counter.Mean"> <summary>Returns the mean value of all accumulated values</summary> <returns>The mean value, i.e. <see cref="F:Counter.value"/> / <see cref="F:Counter.n"/></returns> </members> </doc> XML file can be viewed in HTML using Visual Studio. elements are not nested hierarchically! types of fields and methods are not storen in the XML file!

145 XML Tags Predefined Tags User-defined Tags Main tags
<summary> short description of a program element </summary> <remarks> extensive description of a program element </remarks> <example> sample code </example> <param name="ParamName"> description of a parameter </param> <returns> description of the return value </returns> <exception [cref="ExceptionType"]> used in the documentation of a method: describes an exception </exception> Teil einer anderen Beschreibung <code> multi-line code pieces </code> <c> short code pieces in the text </c> <see cref="ProgramElement"> name of a crossreference link </see> <paramref name="ParamName"> name of a parameter </paramref> User-defined Tags Users may add arbitrary tags, e.g. <author>, <version>, ...

146 Problems Without Generic Types
Assume we need a class that can work with arbitrary objects class Buffer { private object[] data; public void Put(object x) {...} public object Get() {...} } Problems Type casts needed buffer.Put(3); // boxing imposes run-time costs int x = (int) buffer.Get(); // type cast (unboxing) imposes run-time costs One cannot statically enforce homogeneous data structures buffer.Put(3); buffer.Put(new Rectangle()); Rectangle r = (Rectangle) buffer.Get(); // can result in a run-time error! Special types IntBuffer, RectangleBuffer, ... introduce redundancy

147 Generic Class Buffer Usage Benefits generic type placeholder type
class Buffer<Element> { private Element[] data; public Buffer(int size) {...} public void Put(Element x) {...} public Element Get() {...} } works also for structs and interfaces placeholder type Element can be used like a normal type Usage Buffer<int> a = new Buffer<int>(100); a.Put(3); // accepts only int parameters; no boxing int i = a.Get(); // no type cast needed! Buffer<Rectangle> b = new Buffer<Rectangle>(100); b.Put(new Rectangle()); // accepts only Rectangle parameters Rectangle r = b.Get(); // no typ cast needed! Benefits homogeneous data structure with compile-time type checking efficient (no boxing, no type casts)

148 What Happens Behind the Scene?
Compiler generates CIL code for class Buffer with a placeholder for Element. class Buffer<Element> {...} Instantiation with value types At run time the CLR generates a new class Buffer<int> in which Element is replaced with int. Buffer<int> a = new Buffer<int>(); Buffer<int> b = new Buffer<int>(); Uses existing Buffer<int>. At run time the CLR generates a new class Buffer<float> in which Element is replaced with float. Buffer<float> c = new Buffer<float>(); Buffer<string> a = new Buffer<string>(); At run time the CLR generates a new “class” impl. Buffer<object> which can work with all reference types. Buffer<string> b = new Buffer<string>(); Uses existing Buffer<object>. Instantiation with reference types Buffer<Node> b = new Buffer<Node>(); Uses existing Buffer<object> code, but CLR generates new “description”, i.e. Method Table, for Buffer<Node> class.

149 Generic Buffer in ILDASM

150 Multiple Placeholder Types
Buffer with priorities class Buffer <Element, Priority> { private Element[] data; private Priority[] prio; public void Put(Element x, Priority prio) {...} public void Get(out Element x, out Priority prio) {...} } Usage Buffer<int, int> a = new Buffer<int, int>(); a.Put(100, 0); int elem, prio; a.Get(out elem, out prio); Buffer<Rectangle, double> b = new Buffer<Rectangle, double>(); b.Put(new Rectangle(), 0.5); Rectangle r; double prio; b.Get(out r, out prio); C++ allows also placeholders for constants, C# does not

151 Constraints Constraints about placeholder types are specified as base types interface or base class class OrderedBuffer <Element, Priority> where Priority: IComparable { Element[] data; Priority[] prio; int lastElem; ... public void Put(Element x, Priority p) { int i = lastElement; while (i >= 0 && p.CompareTo(prio[i]) > 0) {data[i+1] = data[i]; prio[i+1] = prio[i]; i--;} data[i+1] = x; prio[i+1] = p; } Allows operations on instances of placeholder types Usage OrderedBuffer<int, int> a = new OrderedBuffer<int, int>(); a.Put(100, 3); parameter must implement IComparable

152 Multiple Constraints Usage must be a subclass of MyClass
class OrderedBuffer <Element, Priority> where Element: MyClass where Priority: IComparable, ISerializable { ... public void Put(Element x, Priority p) {...} public void Get(out Element x, out Priority p) {...} } Usage OrderedBuffer<MySubclass, MyPrio> a = new OrderedBuffer<MySubclass, MyPrio>(); ... a.Put(new MySubclass(), new MyPrio(100)); must implement IComparable and ISerializable must be a subclass of MyClass

153 Constructor Constraint
For creating objects of a generic types class Stack<T, E> where E: Exception, new() { T[] data = ...; int top = -1; public void Push(T x) { if (top >= data.Length) throw new E(); else data[++top] = x; } specifies that the placeholder E must have a parameterless constructor. class MyException: Exception { public MyException(): base("stack overflow or underflow") {} } Usage Stack<int, MyException> stack = new Stack<int, MyException>(); ... stack.Push(3);

154 Overview of Constraints
Description where T: struct The type argument must be a value type. Any value type except Nullable can be specified. where T : class The type argument must be a reference type, including any class, interface, delegate, or array type. where T : new() The type argument must have a public parameterless constructor. When used in conjunction with other constraints, the new() must be specified last. where T : BaseClassName The type argument must be or derive from the specified base class. where T : InterfaceName The type argument must be or implement the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic. where T : U The type argument supplied for T must be or derive from the type argument supplied for U. This is called a naked type constraint.

155 Genericity and Inheritance
can also implement generic interfaces class Buffer <Element>: List<Element> { ... public void Put(Element x) { this.Add(x); // Add is inherited from List } From which classes may a generic class be derived? from a non-generic class class T<X>: B {...} from an instantiated generic class class T<X>: B<int> {...} from a generic class class T<X>: B<X> {...} with the same placeholder

156 Assignment Compatibility
Assigning T<x> to a non-generic base class A class A {...} class B<X>: A {...} class C<X,Y>: A {...} B<X> C<X,Y> ... A a1 = new B<int>(); A a2 = new C<int, float>(); B<int> B<float> ... C<int,float> C<float,int> ... class A<X> {...} class B<X>: A<X> {...} class C<X,Y>: A<X> {...} A<int> a1 = new B<int>(); A<int> a2 = new C<int, float>(); Assigning T<x> to a generic base class A<X> B<X> C<X,Y> ... A<int> a3 = new B<short>(); illegal ok, if corresponding placeholders are replaced by the same type

157 Overriding Methods class Buffer<Element> { ... public virtual void Put(Element x) {...} } Methods inherited from an instantiated generic class class MyBuffer: Buffer<int> { ... public override void Put(int x) {...} } Element is replaced by the concrete type int class MyBuffer<Element>: Buffer<Element> { ... public override void Put(Element x) {...} } Methods inherited from a generic class Element remains to be a placeholder The following is illegal (it is not allowed to inherit a placeholder) class MyBuffer: Buffer<Element> { ... public override void Put(Element x) {...} }

158 Run-time Type Checks Instantiated generic types can be used like non-generic types Buffer<int> buf = new Buffer<int>(20); object obj = buf; if (obj is Buffer<int>) buf = (Buffer<int>) obj; Type t = typeof(Buffer<int>); Console.WriteLine(t.Name); // => Buffer’1[System.Int32] Reflection yields also the concrete types substituted for the placeholders!

159 Generic Methods Methods that can work with arbitrary data types Usage
static void Sort<T> (T[] a) where T: IComparable { for (int i = 0; i < a.Length-1; i++) { for (int j = i+1; j < a.Length; j++) { if (a[j].CompareTo(a[i]) < 0) { T x = a[i]; a[i] = a[j]; a[j] = x; } can sort any array as long as the array elements implement IComparable Usage int[] a = {3, 7, 2, 5, 3}; ... Sort<int>(a); // a == {2, 3, 3, 5, 7} string[] s = {"one", "two", "three"}; Sort<string>(s); // s == {"one", "three", "two"} From the method parameters the compiler can usually infer the concrete type that is to be substituted for the placeholder type; so one can simply write: Sort(a); // a == {2, 3, 3, 5, 7} Sort(s); // s == {"one", "three", "two"}

160 Generic Delegates A check method is passed,
delegate bool Check<T>(T value); class Payment { public DateTime date; public int amount; } class Account { ArrayList payments = new ArrayList(); public void Add(Payment p) { payments.Add(p); } public int AmountPayed(Check<Payment> matches) { int val = 0; foreach (Payment p in payments) if (matches(p)) val += p.amount; return val; A check method is passed, which checks for every Payment, whether it is eligible bool PaymentsAfter(Payment p) { return DateTime.Compare(p.date, myDate) >= 0; } ... myDate = new DateTime(2001, 11, 9); int val = account.AmountPayed(new Check<Payment>(PaymentsAfter));

161 Null Values Setting a value to null Comparing a value against null
void Foo<T>() { T x = null; // error T y = 0; // error T z = default(T); // ok! 0, '\0', false, null } Comparing a value against null void Foo<T>(T x) { if (x == null) { Console.WriteLine(true); } else { Console.WriteLine(false"); } Foo(3); // false Foo(0); // false Foo("Hello"); // false Foo<string>(null); // true for reference types x == null does a comparison for nullable types x == null does a comparison for value types x == null returns false

162 Differences to Other Languages
similar Syntax template <typename Element> class Buffer { ... void Put(Element x); } Buffer<int> b1; Buffer<int> b2; compiler generates a new class for every instantiation no constraints, less type-safe (“constraints” imposed by template code) placeholders can also be used for constants and pointers Java since Version 1.5 placeholders can only be instantiated with reference types implemented with type casts (imposes run-time costs) reflection does not yield exact type information about placeholders

163 Class Math (1) public sealed class Math {
public const double PI = ; public const double E = ; public static T Abs(T val); // T sbyte, short, int, long, float, double, decimal public static T Sign(T val); public static T1 Min(T1 x, T1 y); // T1 ... T, byte, ushort, uint, ulong public static T1 Max(T1 x, T1 y); public static double Round(double x); public static double Floor(double x); public static double Ceiling(double x); Überblick

164 Class Math (2) … public static double Sqrt(double x);
public static double Pow(double x, double y); public static double Exp(double x); public static double Log(double x); public static double Log10(double x); public static double Sin(double x); public static double Cos(double x); public static double Tan(double x); public static double Asin(double x); public static double Acos(double x); public static double Atan(double x); } Überblick

165 Class Random public class Random { public Random();
public Random(int seed); public virtual int Next(); // 0 <= res <= int.MaxVal public virtual int Next(int x); // 0 <= res < x public virtual int Next(int x, int y); // x <= res < y public virtual double NextDouble(); // 0.0 <= res < 1.0 public virtual void NextBytes(byte[] b); // fills b with random numbers } Überblick

166 Working with Strings Example „String":
Classes System.String and System.Text.StringBuilder Objects of type String are immutable! Example „String": string s = "Hello"; s += ", There"; char c = s[5]; // Indexer returns ',' Operation == compares the values not the references (Java)! string s2 = "Hello, There"; if(s == s2) // returns true! Compare references as follows: if((object)s == (object)s2) // returns false! Überblick

167 Class String public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable public char this[int index] {get;} public int Length {get;} public static int Compare(string strA, string strB); // Culture! public static int CompareOrdinal(string strA, string strB); // without Culture! public static string Format(string format, object arg0); public int IndexOf(string); public int IndexOfAny(char[] anyOf); public int LastIndexOf(string value); public string PadLeft(int width, char c); // s.PadLeft(10,'.');  ".....Hello" public string[] Split(params char[] separator); public string Substring(int startIndex, int length); ... } Überblick

168 Class StringBuilder StringBuilder is more effective for manipulating strings public sealed class StringBuilder { public int Capacity {get; set;} public int Length {get; set;} StringBuilder Append(...); StringBuilder AppendFormat(...); StringBuilder Insert(int index, ...); StringBuilder Remove(int startIndex, int length); StringBuilder Replace(char oldChar, char newChar); string ToString(); } Reserved size Length of the string Appending, inserting and removing characters Creating String object Überblick

169 Threading Name space System.Threading supports threads
run-time control synchronisation thread pooling Important types of System.Threading are classes Thread and ThreadPool enumerations ThreadState and ThreadPriority class Monitor exceptions ThreadAbortException and ThreadInterruptedException delegates TreadStart, WaitCallback, TimerCallback, IOCompletionCallback, … Überblick

170 Class Thread public sealed class Thread {
public Thread(ThreadStart start); public ThreadPriority Priority {get; set;} public ThreadState ThreadState {get;} public bool IsAlive {get;} public bool IsBackground {get; set;} public void Start(); public static void Sleep(int time); public void Suspend(); public void Resume(); public void Join(); public void Interrupt(); public void Abort(); public static void ResetAbort(); public static Thread CurrentThread {get;} } Constructor with ThreadStart delegate Setting/getting the priority Current state Properties liveliness, background Methods for controlling the thread Gets the currently running thread Überblick

171 ThreadStart, ThreadPriority and ThreadState
public delegate void ThreadStart(); public sealed class Thread { public Thread( ThreadStart start); public ThreadPriority Priority {get; set;} public ThreadState ThreadState {get;} } public enum ThreadPriority { Highest, AboveNormal, Normal, BelowNormal, Lowest, } public enum ThreadState { Background, Unstarted, Running, WaitSleepJoin, SuspendRequested, Suspended, AbortRequested, Stopped } Überblick

172 Creating a New Thread Implementing a ThreadStart delegate
using System.Threading public class ThreadExample { public static void RunT0() { for(int i=0; i<10000; i++) { Console.Write(„x“); Thread.Sleep(100); } Creating Thread with delegate to method RunT0 and starting it public static void main(string[] args) { // main thread starts a new thread which runs RunT0 method Thread t0 = new Thread( new ThreadStart(RunT0)); t0.Start(); Überblick

173 State diagram (simplified)
Thread States Enumeration ThreadState defines the states of a thread State diagram (simplified) public enum ThreadState { AbortRequested, Background,, Running, Stopped, StopRequested, Suspended, SuspendRequested, Unstarted, WaitSleepJoin } unstarted Running Suspend Requested WaitSleepJoin AbortRequested Suspend() Wait(),Sleep(),Join() Abort() Suspended Resume() Interrupt() Stopped Pulse() Start() Überblick

174 Foreground and Background Threads
Two different types of threads: Foreground und Background As long as a foreground thread is running, the program will not terminate running background threads cannot prevent the program from terminating A background thread is created by setting the property IsBackground Thread bgThread = new Thread(new ThreadStart(…)); bgThread.IsBackground = true; Überblick

175 Thread Pools Class ThreadPool enable the automatic management of a collection of threads Used for threads that spend most of their time in the waiting state The system uses a collection of worker threads to manage the registered tasks All the tasks that are registered in a thread pool are processed by the worker threads But: No priorities No threads that use too much processor time No direct access to the threads (e.g.: to stop) Überblick

176 Class ThreadPool public sealed class ThreadPool {
public static void GetAvailableThreads(out int w, out int aIOs); public static void GetMaxThreads(out int w, out int aIOs); public static bool QueueUserWorkItem( WaitCallback task); public static bool QueueUserWorkItem( WaitCallback task, object state); } Number of available worker and IO threads Maximal number of worker and IO threads Registration of a task as WaitCallback delegate WaitCallback delegate public delegate void WaitCallback(object state ); Überblick

177 Example: ThreadPool Definition of the task
Getting the number worker and IO threads Adding a new task to the pool public static WorkerTask(object state) { while (…) { … // do something short Thread.Sleep(…); // then sleep } int maxWorkers, availWorkers; int maxIOs, availIOs; ThreadPool.GetMaxThreads(out maxWorkers, out maxIOs); ThreadPool.GetAvailableThreads(out availWorkers, out availIOs); object state = …; ThreadPool.QueueUserWorkItem(new WaitCallback(WorkerTask), state); Überblick

178 Synchronisation with lock
lock statement is used for synchronisation of threads when accessing common resources lock statement sets lock for an object realizes mutual exclusion public class LockExample { public static void RunT0() { lock(Console.Out) { for(int i = 0; i < 10; i++) { // Console can be used exclusively Console.Write("x“); Thread.Sleep(100); } Überblick

179 Class Monitor Class Monitor realizes basic mechanism for synchronisation lock statement is realized using Monitor; is short form for: public sealed class Monitor { public static void Enter(object obj); public static bool TryEnter(object obj); public static void Exit(object obj); public static void Wait(object obj); public static bool Pulse(object obj); public static void PulseAll(object obj); } tries to get lock for obj and blocks tries to get lock for obj and returns releases lock for obj brings thread into the waiting state, releases locks awakens next thread waiting for obj awakens all threads waiting for obj Monitor.Enter(obj) try { } finally { Monitor.Exit(obj) } lock (obj) { } Überblick

180 Using Monitor Enter blocks when lock is not available
TryEnter tries to get lock without blocking; returns false when lock is not available Enter: with blocking TryEnter: without blocking public class MonitorExample { private Queue lpt; public void AddElemBlocking (object elem) { try { Monitor.Enter (lpt.SyncRoot); lpt.Enqueue (elem); } catch (Exception e) { } finally { Monitor.Exit (lpt.SyncRoot); public bool AddElemNonBlocking (object elem) { try { if (! Monitor.TryEnter (lpt.SyncRoot)) return false; lpt.Enqueue (elem); } catch (Exception e) { } finally { Monitor.Exit (lpt.SyncRoot); return true; Überblick

181 Wait and Pulse With Wait and Pulse threads can be synchronized based on an object state Releases locks and waits to be waked up Wakes up next or all threads waiting for obj public static void Wait(object obj); public static bool Wait(object obj, int millies); public static bool Pulse(object obj); public static void PulseAll(object obj); lock (obj) { ... Monitor.Wait(obj); } lock (obj) { ... Monitor.Pulse(obj); } Überblick

182 Example Wait and Pulse: Buffer
public class Buffer { const int size = 16; char[ ] buf = new char[size]; int head = 0, tail = 0, n = 0; public void Put(char ch) { lock(this) { while (n >= size) Monitor.Wait(this); buf[tail] = ch; tail = (tail + 1) % size; n++; Monitor.Pulse(this); } public char Get() { while (n <= 0) Monitor.Wait(this); char ch = buf[head]; head = (head + 1) % size; n--; return ch; Lock buffer to add a character While buffer is full, release lock and wait Wake up waiting threads Lock buffer to retrieve character While buffer is empty, release lock and wait Wake up waiting threads Überblick

183 Reflection Permits access to meta-information of types at run-time
System.Reflection allows: Getting meta-information about assemblies, modules and types Getting meta-information about the members of a type Dynamic creation of instances of a type at run-time Search for methods and their dynamic invocation at run-time Accessing values of properties and fields of an object Design of new types at run time  namespace System.Reflection.Emit Überblick

184 Reflection Class Hierarchy
Überblick

185 Class Assembly Class Assembly loads assemblies and their meta-data
Provides access to its meta-data public class Assembly { public static Assembly GetExecutingAssembly(); public static Assembly GetAssembly(Type type); public static Assembly Load(string name); public virtual string FullName {get;} public virtual string Location {get;} public virtual MethodInfo EntryPoint {get;} public Module[] GetModules(); public virtual Type[] GetTypes(); public virtual Type GetType(string typeName); public object CreateInstance(string typeName); ... } Get “my” assembly Get assembly where type is defined Loading an assembly Name, storage location, entry point of the assembly Getting modules and all in the assembly defined types Getting type with name typeName Creation of an object of type typeName Überblick

186 Class Type Type used for meta-description of all types in the run-time system Provides access to the meta-information about its members Type t1 = “Hello”.GetType(); Type t2 = typeof(string); Type t3 = typeof(System.String); // t1 == t2 && t2 == t3 public abstract class Type : MemberInfo, IReflect { public abstract Type BaseType {get;}; public abstract string FullName {get;}; public Type[] GetInterfaces(); public bool IsAbstract {get;}; public bool IsClass {get;}; public bool IsPublic {get;}; public ConstructorInfo[] GetConstructors(); public virtual EventInfo[] GetEvents(); public FieldInfo[] GetFields(); public MethodInfo[] GetMethods(); public PropertyInfo[] GetProperties(); ... Direct base type Type name List of implemented interfaces Properties of type Getting constructors, events, fields, methods, properties Überblick

187 Example: Reflection (1)
C# program "HelloWorld" namespace Hello { using System; public class HelloWorld { public static void Main(string[] args) { Console.WriteLine("HelloWorld"); } public override string ToString() { return "Example HelloWorld"; Loading the assembly "HelloWorld.exe": Assembly a = Assembly.Load("HelloWorld"); Compiling and creating assembly csc HelloWorld.cs HelloWorld.exe Überblick

188 Example: Reflection (2)
Print all existing types in a given assembly Type[] types = a.GetTypes(); foreach (Type t in types) Console.WriteLine(t.FullName); Print all existing methods of a given type Type hw = a.GetType("Hello.HelloWorld"); MethodInfo[] methods = hw.GetMethods(); foreach (MethodInfo m in methods) Console.WriteLine(m.Name); Überblick

189 Example: Reflection (3)
Create a new instance of a given type Assembly a = Assembly.Load("HelloWorld"); object o = a.CreateInstance("Hello.HelloWorld"); Get method ToString(), which has no parameters Type hw = a.GetType("Hello.HelloWorld"); MethodInfo mi = hw.GetMethod("ToString"); object retVal = mi.Invoke(o, null); Überblick

190 Files and Directories Directory:
Namespaces System.IO.File and System.IO.Directory for working with files and directories Directory: static methods for manipulating directories File: static methods for manipulating files DirectoryInfo: represents a directory FileInfo: represents a file Überblick

191 Class Directory public sealed class Directory {
public static DirectoryInfo CreateDirectory(string path); // creates directories and subdirectories public static void Move(string src, string dest); // moves directory src to dest public static void Delete(string path); // deletes an empty directory public static void Delete(string path, bool recursive); // deletes directory with contents public static bool Exists(string path); // checks if directory exists public static string[] GetFiles(string path); // returns all file names in path public static string[] GetFiles(string path, string searchPattern); public static string[] GetDirectories(string path); // returns all directory names in path public static string[] GetDirectories(string path, string searchPattern); public static DirectoryInfo GetParent(string path); // returns the parent directory public static string GetCurrentDirectory(); // returns current working directory public static void SetCurrentDirectory(string path); // sets current working directory public static string[] GetLogicalDrives(); // returns names of logical drives (e.g. “c:\”) public static DateTime GetCreationTime(string path); // returns creation date & time public static DateTime GetLastAccessTime(string path); public static DateTime GetLastWriteTime(string path); public static void SetCreationTime(string path, DateTime t); // sets creation date & time public static void SetLastAccessTime(string path, DateTime t); public static void SetLastWriteTime(string path, DateTime t); } Überblick

192 Class DirectoryInfo public sealed class DirectoryInfo : FileSystemInfo { //----- constructor public DirectoryInfo(string path); // path specifies the directory //----- properties public override string Name { get; } // returns directory name without the path public override bool Exists { get; } // indicates if this directory exists public DirectoryInfo Parent { get; } // returns the parent directory public DirectoryInfo Root { get; } // returns the root directory //----- methods public void Create(); // create a new directory, if it does not exist public DirectoryInfo CreateSubdirectory(string path); // creates a subdirectory public void MoveTo(string destDir); // moves this directory to destDir public void Delete(); // deletes this directory, if it is empty public void Delete(bool recursive); // deletes this directory and its contents public FileInfo[] GetFiles(); // returns all files in this directory public FileInfo[] GetFiles(string pattern); // returns matching files in this directory public DirectoryInfo[] GetDirectories(); // returns all directories in this directory public DirectoryInfo[] GetDirectories(string pattern); // returns all matching directories public FileSystemInfo[] GetFileSystemInfos(); // returns all files and directories public FileSystemInfo[] GetFileSystemInfos(string pattern); // returns files and directories for pattern public override ToString(); // returns the path given in the constructor } Überblick

193 Class File public sealed class File {
public static FileStream Open(string path, FileMode mode); public static FileStream Open(string path, FileMode m, FileAccess a); public static FileStream Open(string p, FileMode m, FileAccess a, FileShare s); public static FileStream OpenRead(string path); public static FileStream OpenWrite(string path); public static StreamReader OpenText(string path); // returns Reader for reading text public static StreamWriter AppendText(string path); // returns Writer for appending text public static FileStream Create(string path); // create a new file public static FileStream Create(string path, int bufferSize); public static StreamWriter CreateText(string path); public static void Move(string src, string dest); public static void Copy(string src, string dest); // copies file src to dest public static void Copy(string src, string dest, bool overwrite); public static void Delete(string path); public static bool Exists(string path); public static FileAttributes GetAttributes(string path); public static DateTime GetCreationTime(string path); public static DateTime GetLastAccessTime(string path); public static DateTime GetLastWriteTime(string path); public static void SetAttributes(string path, FileAttributes fileAttributes); public static void SetCreationTime(string path, DateTime creationTime); public static void SetLastAccessTime(string path, DateTime lastAccessTime); public static void SetLastWriteTime(string path, DateTime lastWriteTime); } Überblick

194 Class FileInfo public sealed class FileInfo : FileSystemInfo {
//----- constructors public FileInfo(string fileName); // creates a new FileInfo object for a file fileName //----- properties public override string Name { get; } // name of this file public long Length { get; } // size of this file public override bool Exists { get; } // indicates if this file exists public DirectoryInfo Directory { get; } // directory containing this file public string DirectoryName { get; } // name of the directory containing this file //----- methods public FileStream Open(FileMode m); // open a FileStream to this file public FileStream Open(FileMode m, FileAccess a); public FileStream Open(FileMode m, FileAccess a, FileShare s); public FileStream OpenRead(); // opens a read-only FileStream to this file public FileStream OpenWrite(); // open a write-only FileStream to this file public StreamReader OpenText(); // returns a UTF8 reader for reading text public StreamWriter AppendText(); // returns a StreamWriter for appending text public FileStream Create(); // returns FileStream to this newly created file public StreamWriter CreateText(); // returns Writer to this newly created text file public void MoveTo(string dest); // move this file to dest public FileInfo CopyTo(string dest); // copies this file to dest public FileInfo CopyTo(string dest, bool overwrite); // copies to and overwrites dest public override Delete(); // deletes this file public override string ToString(); // returns entire path of this file } Überblick

195 Example: Directories and Files
Putting out the directories and files in "c:\\" Output using System; using System.IO; public class DirectoryExample { public static void Main() { DirectoryInfo dir = Directory.CreateDirectory("c:\\"); Console.WriteLine(" Directories "); DirectoryInfo[] dirs = dir.GetDirectories(); foreach (DirectoryInfo d in dirs) Console.WriteLine(d.Name); Console.WriteLine (" Files "); FileInfo[] files = dir.GetFiles(); foreach (FileInfo f in files) Console.WriteLine(f.Name); } Directories Documents and Settings I386 Program Files System Volume Information WINNT Files AUTOEXEC.BAT boot.ini CONFIG.SYS IO.SYS MSDOS.SYS NTDETECT.COM ntldr pagefile.sys Überblick

196 Example: Handling plug-ins
“Plug-in” is any class implementing IMyPlugin interface string[] files = Directory.GetFiles(path, "*.dll"); // returns full paths foreach (string f in files) { Assembly a = Assembly.LoadFile(f); Type[] types = a.GetTypes(); foreach (Type t in types) { if (t.IsClass) { if (t.GetInterface(“IMyPlugin”) != null) { IMyPlugin p = (IMyPlugin) a.CreateInstance(t.FullName); // add p to list of all installed plug-ins }

197 Collections Types for dealing with sets, lists and dictionaries
Überblick

198 IEnumerable and IEnumerator (1)
Anything which is enumerable is represented by interface IEnumerable IEnumerator realizes an iterator interface IEnumerable { IEnumerator GetEnumerator(); } interface IEnumerator { object Current {get;} bool MoveNext(); void Reset(); } Überblick

199 IEnumerable and IEnumerator (2)
following statement: foreach (ElementType element in collection) statement; is translated into: IEnumerator enumerator = ((IEnumerable) collection).GetEnumerator(); try { ElementType element; while (enumerator.MoveNext()) { element = (ElementType) enumerator.Current; statement; } } finally { IDisposable disposable = enumerator as IDisposable; if (disposable != null) disposable.Dispose();

200 IEnumerable and IEnumerator (3)
Classes which implement IEnumerable are: Array ArrayList String Hashtable and many more. For all IEnumerables foreach–statement can be used Example: int[] a = {1, 6, 8, 9, 15}; // object of abstract type Array foreach (int i in a) System.Console.WriteLine(i); Überblick

201 Interface ICollection
Basic interface for collections int Count {get;} number of elements bool IsSynchronized {get;} collection synchronised? object SyncRoot {get;} returns object for synchronisation void CopyTo(Array a, int index); copies the elements into array (starting at position index) interface ICollection { //---- Properties int Count {get;} bool IsSynchronized {get;} object SyncRoot {get;} //---- Methods void CopyTo(Array a, int index); } Überblick

202 Interface IList Interface for object collections with a defined order
object this [ int index ] {get; set;} int Add(object value); void Insert(int index,object value); void Remove(object value); void RemoveAt(int index); void Clear(); bool Contains(object value); bool IsFixedSize {get;} bool IsReadOnly {get;} ... } Indexer for accessing elements based on position Adding, inserting and removing elements Testing containment of elements Is list of fixed length? Is list read-only? Überblick

203 Class Array (1) Arrays in .NET are instances of classes derived from base class Array Array implements IList, ICollection and IEnumerable Arrays are of fixed size (isFixedSize() == true) Array provides a rich interface public abstract class Array : ICloneable, IList, ICollection, IEnumerable { //---- Properties public int Length {get;} public int Rank {get;} //----- Methods public int GetLength(int dimension); public int GetLowerBound(int dimension); public int GetUpperBound(int dimension); public object GetValue(int idx); public object GetValue(int[] idx); public void SetValue(object val, int idx); public void SetValue(object val, int[] idx); Getting length and number of dimensions Getting length and lower and upper bound for each dimension Getting and setting values Überblick

204 Class Array (2) Searching for positions of elements Sorting of arrays
//----- static methods public static int IndexOf(Array a, object val); public static int LastIndexOf(Array a, object value); public static void Sort(Array a); public static void Sort(Array a, IComparer comparer); public static void Reverse(Array a); public static int BinarySearch(Array a, object val); public static int BinarySearch(Array a, object val, IComparer c); public static void Copy(Array srcArray, Array destArray, int len); public static Array CreateInstance(Type elementType, int len); public static Array CreateInstance(Type elementType, int[] len); } Searching for positions of elements Sorting of arrays Binary search in sorted arrays Copying and creating arrays Überblick

205 Example: Array Creation of array with Array.CreateInstance
which is equivalent to Setting values and sorting Output of elements with foreach statement int[] i = (int[]) Array.CreateInstance(typeof(Int32), 6); int[] i = new int[6]; i[0] = 3; i[1] = 1; i[2] = 5; i[3] = 2; i[4] = 9; i[5] = 4; Array.Sort(i); // Sorts the elements in the array foreach (int elem in i) Console.Write("{0} ", elem); Elemente: Überblick

206 Class ArrayList (1) ArrayList realizes dynamically growing list
public class ArrayList : IList, ICollection, IEnumerable, ICloneable { public ArrayList(); public ArrayList(ICollection c); public ArrayList(int capacity); virtual int Capacity {get;set;} public virtual ArrayList GetRange(int index, int count); public virtual void AddRange(ICollection c); public virtual void InsertRange(int index, ICollection c); public virtual void SetRange(int i, ICollection c); public virtual void RemoveRange(int index, int count); Constructors Capacity Accessing, inserting, setting, removing elements Überblick

207 Class ArrayList (2) Sorting and searching Creation of wrappers
public virtual void Sort(); public virtual void Reverse(); public virtual int BinarySearch(object o); public virtual int LastIndexOf(object o); public static ArrayList Adapter(IList list); public static ArrayList FixedSize(ArrayList l); public static ArrayList ReadOnly(ArrayList l); public static ArrayList Synchronized(ArrayList list); public virtual void CopyTo(Array a); public virtual object[] ToArray(); public virtual void TrimToSize(); } Sorting and searching Creation of wrappers Copying elements Trimming to actual size Überblick

208 Example: ArrayList Creating ArrayList and adding values
Sorting the elements in the ArrayList Inverting the elements in the ArrayList ArrayList a = new ArrayList(); a.Add(3); al.Add(1); al.Add(2); al.Add(4); al.Add(9); a.Sort(); foreach (int i in a) Console.WriteLine(i); Elemente: a.Reverse(); foreach (int i in a) Console.WriteLine(i); Elemente: Überblick

209 Synchronized ArrayList
Thread modifying an ArrayList: ArrayList m_List; static void WriterThread() { Debug.Assert(m_List.IsSynchronized); for (int i=0; ; i++) { m_List.Add(i); m_List.RemoveAt(0); } Other thread is enumerating the ArrayList: m_List = ArrayList.Synchronized(new ArrayList()); Thread wt = new Thread(new ThreadStart(WriterThread)); wt.IsBackground = true; wt.Start(); try { for (int i=0; i<100; i++) { lock (m_List.SyncRoot) { foreach (int n in m_List) { Console.Write(n); Thread.Sleep(0); Console.WriteLine(); } catch (InvalidOperationException) {}

210 Sorting: IComparable and IComparer
IComparable is interface for types with order Classes implementing IComparable are values types like Int32, Double, DateTime, … class Enum as base class of all enumeration types class String IComparer is interface for the realization of compare operators IComparer implementations: Comparer, CaseInsensitiveComparer: for string comparisons public interface IComparable { int CompareTo(object obj); // -1 if this < obj, 0 if this == obj, 1 if this > obj } public interface IComparer { int Compare(object x, object y); // -1 if x < y, 0 if x == y, 1 if x > y } Überblick

211 Example: IComparer Creation of an array of strings
Sorting the strings using a case-insensitive comparer Binary search for a name Inverting the array string[] names = new string[] {“frank”, “john”, “Bill”, “paul”, “Frank”}; IComparer ciComparer = new CaseInsensitiveComparer (); Array.Sort(names, ciComparer); int pos = Array.BinarySearch("John“, ciComparer); names = Array.Reverse(names, ciComparer); Überblick

212 Custom IComparer Implementation
Creation of table of strings: ArrayList table = new ArrayList(); table.Add(new string[] {"John", "Dow", "programmer"}); table.Add(new string[] {"Bob", "Smith", "agent"}); table.Add(new string[] {"Mike", "Black", "assistant"}); Printing the table: foreach (string[] row in table) { Console.WriteLine(String.Join(", ", row)); }

213 Custom IComparer Implementation (2)
Comparer for single table (array) column: class ArrayComparer : IComparer { private int m_Index; public ArrayComparer(int Index) { m_Index = Index; } public int Compare(object x, object y) { IComparable xVal = (IComparable) ((Array) x).GetValue(m_Index); IComparable yVal = (IComparable) ((Array) y).GetValue(m_Index); return xVal.CompareTo(yVal); Printing the table: table.Sort(new ArrayComparer(1)); foreach (string[] row in table) { Console.WriteLine(String.Join(", ", row)); Mike, Black, assistant John, Dow, programmer Bob, Smith, agent

214 Example: IComparable (1)
Type Vector represents two-dimensional vector implements IComparable sorting is done based on the length of the vector public class Vector : IComparable { private double x, y; public Vector(double x, double y) { this.x = x; this.y = y; } public double Length { get { return Math.Sqrt( x*x + y*y ); } } public int CompareTo(object obj) { if(obj is Vector) { if(this.Length < ((Vector)obj).Length) return -1; else if(this.Length > ((Vector)obj).Length) return 1; else return 0; } throw new ArgumentException(); Überblick

215 Example: IComparable (2)
Creation of array of Vector objects Vector[] vArray = { new Vector(1.5,2.3), new Vector(3,6), new Vector(2,2) }; Elements in array are sorted based on length of vectors Array.Sort(vArray); dumpArray(vArray); Array.Reverse(vArray); Überblick

216 Interface IDictionary
IDictionary is interface for collections of key-value pairs Keys Values Indexer for accessing elements by key Adding, removing, containment Accessing an iterator for key-value pairs interface IDictionary : ICollection, IEnumerable { ICollection Keys {get;}; ICollection Values {get;}; object this[object key] {get; set;} void Add(object key, object value); void Remove(object key); bool Contains(object key); IDictionaryEnumerator GetEnumerator(); } Überblick

217 IDictionaryEnumerator and DictionaryEntry
IDictionaryEnumerator is iterator over key-value pairs IDictionaryEntry represents key-value pair interface IDictionary : ICollection, IEnumerable { IDictionaryEnumerator GetEnumerator(); } public struct DictionaryEntry { //----- Constructor public DictionaryEntry (object key, object value); //----- Properties public object Key {get;}; public object Value {get;}; } public interface IDictionaryEnumerator : IEnumerator { //----- Properties public DictionaryEntry Entry {get;}; public object Key {get;}; public object Value {get;}; } Überblick

218 Dictionary Hashtable Hashtable is an implementation of IDictionary
organised by hash code of keys  key objects must implement GetHashCode and Equals methods public class Hashtable : IDictionary, ICollection, IEnumerable, … { public Hashtable(); public Hashtable(IDictionary d); public Hashtable(int capacity); public virtual object this[object key] {get; set;} public virtual bool ContainsKey(object key); public virtual bool ContainsValue(object val); protected IHashCodeProvider Hcp {get; set;} } Constructors Indexer for accessing elements by key Testing, if key and value contained Setting and getting a HashCodeProviders ! Überblick

219 Example: Hashtable Creating Hashtable and adding Person objects using the social security number as key Iterating over the entries and printing out values and keys Testing for containment of an entry with a particular key public class Person { public Person(string fn, string ln) { } public override string ToString() { ... Hashtable h = new Hashtable(); h.Add( , new Person("Mike", "Miller")); h.Add( , new Person("Susanne", "Parker")); h.Add( , new Person("Roland", "Howard")); h.Add( , new Person("Douglas", "Adams")); foreach (DictionaryEntry x in h) Console.WriteLine(x.Value + ": " + x.Key); if (h.Contains( )) Console.WriteLine("Person with SNr : " + h[ ]); Überblick

220 Hashtable as Associative Array
Indexer ([] operator) automatically adds keys/values to the HashTable Iterating over the entries and printing out keys and values Iterating over the keys and printing out keys and values Hashable population = new Hashtable(); population["Vienna"] = ; population["London"] = ; population["Paris"] = ; foreach (DictionaryEntry x in population) Console.WriteLine("{0} = {1}", x.Key, x.Value); foreach (string c in population.Keys) Console.WriteLine("{0} = {1}", c, population[c]); Überblick

221 HashCodeProvider HashCodeProvider allows the creation of hash codes independent of key objects On creation of Hashtable the HashCodeProvider can be set (has to be done together with compatible comparer) Example: public interface IHashCodeProvider { int GetHashCode( object obj ); } public class Hashtable : IDictionary, ICollection, IEnumerable, ISerializable, … { public Hashtable(IHashCodeProvider hcp, IComparer cmp); } Hashtable table = new Hashtable( new CaseInsensitiveHashCodeProvider(), new CaseInsensitiveComparer()); Überblick

222 Dictionary SortedList
SortedList is second implementation of IDictionary dynamic list of key-value pairs sorted by key! public class SortedList : IDictionary, ICollection, … { public SortedList(); public SortedList(IComparer c); public virtual object this[object key] {get; set;}; public virtual object GetByIndex(int i); public virtual object GetKey(int i); public virtual IList GetKeyList(); public virtual IList GetValueList(); public virtual int IndexOfKey(object key); public virtual int IndexOfValue(object value); public virtual void RemoveAt(int i); } Constructors Indexer for accessing elements by key Accessing values and keys based on index position List of keys and values Position of key and value Removing an entry at a given position Überblick

223 ListDictionary Implements IDictionary as a singly linked list (recommended for small amounts of data, less than 10) public class ListDictionary : IDictionary, IEnumerable { // System.Collections.Specialized public ListDictionary(); public int Count { get; } public ICollection Keys { get; } public ICollection Values { get; } public object this[object key] { get; set; } public void Clear(); public void Add(object key, object value); public void Remove(object key); public bool Contains(object key); public virtual bool Equals(object x); public IDictionaryEnumerator GetEnumerator(); ... } Example ListDictionary population = new ListDictionary(); population["Vienna"] = ; // same as population.Add("Vienna", ); population["London"] = ; population["Paris"] = ; foreach (DictionaryEntry x in tab) Console.WriteLine("{0} = {1}", x.Key, x.Value);

224 Special Collections Queue Stack BitArray
public class Queue : ICollection, IEnumerable, ICloneable { public virtual void Clear(); public virtual bool Contains(object o); public virtual object Dequeue(); public virtual void Enqueue(object o); public virtual object Peek(); } Queue Stack BitArray public class Stack : ICollection, IEnumerable, ICloneable { public virtual void Clear(); public virtual bool Contains(object o); public virtual object Peek(); public virtual object Pop(); public virtual void Push(object o); } public sealed class BitArray : ICollection, IEnumerable, ICloneable { public bool this[int index] {get; set;} public int Length {get; set;} public BitArray And(BitArray val); public BitArray Not(); public BitArray Or(BitArray a); } Überblick

225 Stack (LIFO) public class Stack : ICollection, IEnumerable, ICloneable { // System.Collections public Stack(); // default capacity = 10 public Stack(int initCapacity); public virtual int Count { get; } public virtual void Clear(); public virtual void Push(object x); public virtual object Pop(); public virtual object Peek(); // returns topmost element without removing it public virtual bool Contains(object x); public virtual object Clone(); public virtual IEnumerator GetEnumerator(); public virtual object[] ToArray(); ... } Example Stack s = new Stack(); for (int i = 0; i <= 20; i++) s.Push(i); // stack grows on demand while (s.Count > 0) Console.Write("{0} ", (int)s.Pop()); // returns

226 Queue (FIFO) public class Queue : ICollection, IEnumerable, ICloneable { // System.Collections public Queue(); // variants exist public virtual int Count { get; } public virtual void Clear(); public virtual void Enqueue(object x); public virtual object Dequeue(); public virtual object Peek(); // returns first element without removing it public virtual bool Contains(object x); public virtual object Clone(); public virtual IEnumerator GetEnumerator(); public virtual object[] ToArray(); ... } Example Queue q = new Queue(); q.Enqueue("one"); q.Enqueue("two"); q.Enqueue("three"); foreach (string s in q) Console.Write(s + " "); // one two three // q is still full Console.WriteLine(); while (q.Count > 0) Console.Write((string)q.Dequeue() + " "); // one two three // q is empty

227 BitArray public sealed class BitArray : ICollection, IEnumerable, ICloneable { // System.Collections public BitArray(int capacity); // variants exist public int Length { get; set; } // maximum number of elements public bool this[int i] { get; set; } public BitArray And(BitArray x); // both BitArrays must be of the same size public BitArray Or(BitArray x); public BitArray Xor(BitArray x); public BitArray Not(); public void SetAll(bool val); public object Clone(); public IEnumerator GetEnumerator(); } Example BitArray a = new BitArray(16); // all elements are false BitArray b = new BitArray(16); a[3] = a[4] = a[5] = true; b[4] = b[5] = b[6] = true; a.And(b); // a[4] and a[5] are true b.Xor(a); // only b[6] is true

228 BitVector32 Ligh-weight type for bit arrays of length 32 Example
public struct BitVector32 { // namespace System.Collections.Specialized public BitVector32(int val); // val is interpreted as a bit pattern public int Data { get; } // returns the bit pattern as an int public bool this[int i] { get; set; } public override bool Equals(object x); } Example BitVector32 v = new Bitvector32(12); // v[2] and v[3] are set ( ) v[0] = v[1] = true; Console.WriteLine(v.Data); // 15

229 "BCL-friendly" Custom Classes
In order to cooperate smoothly with other BCL classes, custom classes should override Equals, ToString and GetHashCode overload == and != implement ICloneable public interface ICloneable { object Clone(); } class MyClass : ICloneable { public object Clone() { return MemberwiseClone(); } implement IComparable public interface IComparable { int CompareTo(object obj); // -1: this < obj, 0: this == obj, 1: this > obj class Fraction : IComparable { int n, d; public int CompareTo(object o) { return n*((Fraction)o).d - ((Fraction)o).n*d

230 Namespace System.Collections.Generic
New generic types (in framework 2.0) Classes List<T> Dictionary<T, U> SortedDictionary<T, U> Stack<T> Queue<T> LinkedList<T> corresponds to ArrayList corresponds to Hashtable corresponds to SortedList corresponds to Stack corresponds to Queue new doubly linked list of LinkedListNode<T> Interfaces ICollection<T> IList<T> IDictionary<T, U> IEnumerable<T> IEnumerator<T> IComparable<T> IComparer<T> IEquatable<T>

231 "BCL v2-friendly" Custom Classes 1/3
In order to cooperate smoothly with other BCL classes in the framework 2.0, custom classes should: override ToString and GetHashCode overload == and != implement ICloneable public interface ICloneable { object Clone(); } class MyClass : ICloneable { public object Clone() { return MemberwiseClone(); }

232 "BCL v2-friendly" Custom Classes 2/3
implement IComparable and IComparable<T> public interface IComparable { int CompareTo(object obj); // -1: this < obj, 0: this == obj, 1: this > obj } public interface IComparable<T> { int CompareTo(T obj); // -1: this < obj, 0: this == obj, 1: this > obj class Fraction : IComparable, IComparable<Fraction> { int n, d; public int CompareTo(object o) { return CompareTo((Fraction) o); public int CompareTo(Fraction f) { return n*f.d – f.n*d

233 "BCL v2-friendly" Custom Classes 2/3
override Equals(object) and implement IEquatable<T> public class Object { public virtual bool Equals(Object obj); } public interface IEquatable<T> { bool Equals(T other); class Fraction : IEquatable<Fraction> { // equal to class Fraction : object, IEquatable<Fraction> int n, d; public override bool Equals(object o) { return Equals((Fraction) o); public bool Equals(Fraction f) { return f.n == n && f.d == d;

234 Iterators so far foreach loop can be applied to objects of classes which implement IEnumerable class MyClass: IEnumerable { ... public IEnumerator GetEnumerator() { return new MyEnumerator(...); } class MyEnumerator: IEnumerator { public object Current { get {...} } public bool MoveNext() {...} public void Reset() {...} interface IEnumerable { IEnumerator GetEnumerator(); } MyClass x = new MyClass(); ... foreach (object obj in x) ... complicated to implement!!

235 Iterator Methods Characteristics of an interator method
class MyClass { string first = "first"; string second = "second"; string third = "third"; ... public IEnumerator GetEnumerator() { yield return first; yield return second; yield return third; } Characteristics of an interator method has the signature public IEnumerator GetEnumerator statement body contains at least one yield statement MyClass x = new MyClass(); ... foreach (string s in x) Console.Write(s + " "); // prints "first second third " returns a sequence of values foreach loop traverses this sequence How does an iterator method work? Note MyClass need not implement IEnumerable! Instead of IEnumerator it is better to use IEnumerator<string> (avoids a type cast) IEnumerator<T> is in System.Collections.Generic

236 What Happens Behind the Scene?
returns an object of the following class public IEnumerator<int> GetEnumerator() { try { ... } finally { } class _Enumerator1 : IEnumerator<int> { int Current { get {...} } bool MoveNext() {...} void Dispose() {...} } is translated into foreach (int x in list) Console.WriteLine(x); IEnumerator<int> _e = list.GetEnumerator(); try { while (_e.MoveNext()) Console.WriteLine(_e.Current); } finally { if (_e != null) _e.Dispose(); } MoveNext runs to the next yield statement Dispose executes a possibly existing finally block in the iterator method

237 Implementation class Stack<T>: IEnumerable<T> { T[] items; int count; public void Push(T item) { } public T Pop() { public IEnumerator<T> GetEnumerator() { for (int i = count - 1; i >= 0; --i) { yield return items[i]; } } class Stack<T>: IEnumerable<T> { ... public IEnumerator<T> GetEnumerator() { return new __Enumerator1(this); } class __Enumerator1: IEnumerator<T>, IEnumerator { int __state; T __current; Stack<T> __this; int i; ... public bool MoveNext() { switch (__state) { case 1: goto __state1; case 2: goto __state2; } i = __this.count - 1; __loop: if (i < 0) goto __state2; __current = __this.items[i]; __state = 1; return true; __state1: --i; goto __loop; __state2: __state = 2; return false; } } }

238 yield Statement 2 kinds yields a value for the foreach loop
yield return expr; yields a value for the foreach loop may only occur in an iterator method type of expr must be compatible with - T (if IEnumerator<T>) - object (otherwise) yield break; terminates the iteration may only occur in an iterator method

239 Specific Iterators Standard iterator Specific iterator as a method
class MyList { int[] data = ...; public IEnumerator<int> GetEnumerator() { for (int i = 0; i < data.Length; i++) yield return data[i]; } Standard iterator Specific iterator as a method arbitrary name and parameter list result type IEnumerable or IEnumerable<T> public IEnumerable<int> Range(int from, int to) { if (to > data.Length) to = data.Length; for (int i = from; i < to; i++) yield return data[i]; } Specific iterator as a property arbitrary name result type IEnumerable or IEnumerable<T> public IEnumerable<int> Downwards { get { for (int i = data.Length - 1; i >= 0; i--) yield return data[i]; } MyList list = new MyList(); foreach (int x in list) Console.WriteLine(x); foreach (int x in list.Range(2, 7)) Console.WriteLine(x); foreach (int x in list.Downwards) Console.WriteLine(x);

240 How Specific Iterators are Compiled
returns an object of the following class public IEnumerable<int> Range(int from, int to) { if (to > data.Length) to = data.Length; for (int i = from; i < to; i++) yield return data[i]; } class _Enumerable : IEnumerable<int> { IEnumerator<int> GetEnumerator(); } this returns an object of the following class class _Enumerator : IEnumerator<int> { int from, to; int Current { get {...} } bool MoveNext() {...} void Dispose() {..} } is translated into foreach (int x in list.Range(2, 7)) Console.WriteLine(x); IEnumerator<int> _e = list.Range(2, 7).GetEnumerator(); try { while (_e.MoveNext()) Console.WriteLine(_e.Current); } finally { if (_e != null) _e.Dispose(); }

241 Example: Iterating Over a Tree
class Tree { Node root = null; public void Add(int val) {...} public bool Contains(int val) {...} public IEnumerator<int> GetEnumerator() { return root.GetEnumerator(); } ... Tree tree = new Tree(); foreach (int x in tree) Console.WriteLine(x); Usage Creates an enumerator object for every node of the tree! class Node { public int val; public Node left, right; public Node(int x) { val = x; } public IEnumerator<int> GetEnumerator() { if (left != null) foreach (int x in left) yield return x; yield return val; if (right != null) foreach (int x in right) yield return x; }

242 Simplified Creation of Delegates
delegate void Printer(string s); void Foo(string s) { Console.WriteLine(s); } Printer print; print = new Printer(this.Foo); print = this.Foo; print = Foo; simplified form: delegate type is infered from the type of the left-hand side delegate double Function(double x); double Foo(double x) { return x * x; } Printer print = Foo; Function square = Foo; assigns Foo(string s) assigns Foo(double x) overloading is resolved using the type of the left-hand side

243 Ordinary Delegates class C { int sum = 0; void SumUp(Node p) { sum += p.value; } void Print(Node p) { Console.WriteLine(p.value); } void Foo() { List list = new List(); list.ForAll(SumUp); list.ForAll(Print); } requires the declaration of a named method (SumUp, Print, ...) SumUp and Print cannot access the local variables of Foo => sum must be declared as a global field delegate void Visitor(Node p); class List { Node[] data = ...; ... public void ForAll(Visitor visit) { for (int i = 0; i < data.Length; i++) visit(data[i]); }

244 Anonymous Methods formal parameter code
class List { ... public void ForAll(Visitor visit) { } delegate void Visitor(Node p); class C { void Foo() { List list = new List(); int sum = 0; list.ForAll(delegate (Node p) { Console.WriteLine(p.value); }); list.ForAll(delegate (Node p) { sum += p.value; }); } formal parameter code method code is specified in-place does not require the declaration of a named method anonymous method can access Foo's local variable sum return terminates the anonymous method (not the enclosing method) Restrictions anonymous methods must not have formal parameters of the kind params T[] anonymous methods must not be assigned to object anonymous methods must not access ref or out parameters of the enclosing method

245 Further Simplification
delegate void EventHandler (object sender, EventArgs arg); Button button = new Button(); Button.Click += delegate (object sender, EventArgs arg) { Console.WriteLine("clicked"); }; Can be simplified as follows Button.Click += delegate { Console.WriteLine("clicked"); }; Formal parameters can be omitted if they are not used in the method body Restriction Formal parameters can only be omitted if the delegate type does not have out parameters

246 Outer Variables If anonymous methods access variables of the enclosing method these variables are evacuated into a dummy object (capturing) – all anonymous methods and the enclosing method itself are then using a single “evacuated” variable (see next slide). delegate int Adder(); class Test { static Adder CreateAdder() { int x = 0; return delegate { x++; return x; }; } static void Main() { Adder add = CreateAdder(); Console.WriteLine(add()); x++; return x; dummy object delegate add 1 3 2 The dummy object lives as long as the delegate object Output: 1 2 3

247 Example Output: --- Main: Foo()(); Foo: x = 1 delegate: x = 2
second delegate: x = 13 delegate: x = 14 Foo: x = 14 second delegate: x = 24 Example delegate void MyDelegate(); class Program { static MyDelegate Foo() int x = 1; Console.WriteLine("Foo: x = {0}", x); MyDelegate d = delegate { x++; Console.WriteLine("delegate: x = {0}", x); }; d(); MyDelegate d2 = delegate { x += 10; Console.WriteLine("second delegate: x = {0}", x); }; d2(); Console.WriteLine("Fce: x = {0}", x); return d2; } static void Main(string[] args) Console.WriteLine(“--- Main: Foo()();"); Foo()();

248 Partial Types Benefit file Part1.cs file Part2.cs
public partial class C { int x; public void M1(...) {...} public int M2(...) {...} } file Part1.cs public partial class C { string y; public void M3(...) {...} public void M4(...) {...} public void M5(...) {...} } file Part2.cs Benefit Parts can be grouped by functionality different developers can work on different parts of the class at the same time one part can be machine-generated, other parts can be hand-written Should only be used as an exception

249 Static Classes May only have static fields and methods Benefit
static class Math { public static double Sin(double x) {...} public static double Cos(double x) {...} ... } Benefit shows explicitly that this class contains only static members the compiler can make sure that all members are declared as static Static classes must not be used as types

250 Nullable Types [Serializable]
public struct Nullable<T> where T : struct { public Nullable ( T value ) public bool HasValue { get; } public T Value { get; } public T GetValueOrDefault () public T GetValueOrDefault ( T defaultValue ) public static explicit operator T (Nullable <T> value ) public static implicit operator Nullable<T> ( T value ) } int i = 123; int? x = 456; int? y = null; object o1 = i; // o1 = reference to boxed int 123 object o2 = x; // o2 = reference to boxed int 456 object o3 = y; // o3 = null int i1 = (int)o1; // i1 = 123 int i2 = (int)o2; // i2 = 456 int i3 = (int)o3; // Error, System.NullReferenceException int? ni1 = (int?)o1; // ni1 = 123 int? ni2 = (int?)o2; // ni2 = 456 int? ni3 = (int?)o3; // ni3 = null x == null null == x // !x.HasValue x != null null != x // x.HasValue int? z = x ?? y; // x.HasValue ? x : y int? u = x + y; // (x.HasValue && y.HasValue) ? (x + y) : null

251 Nullable Types, bool?

252 Pragmas using System; class Program { [Obsolete] static void Foo() {}
static void Main() { #pragma warning disable 612 Foo(); #pragma warning restore 612 } }

253 FileSystemWatcher Monitoring the file system using FileSystemWatcher
Changes are signaled by events public class FileSystemWatcher : Component, …{ public FileSystemWatcher(string path); public string Path { get; set; } public string Filter { get; set; } public bool IncludeSubdirectories { get; set; } public event FileSystemEventHandler Changed; public event FileSystemEventHandler Created; public event FileSystemEventHandler Deleted; public event RenamedEventHandler Renamed; public WaitForChangedResult WaitForChanged( WatcherChangeTypes types); } Setting path and filter to define the part of the file system to monitor Include/exclude subdirectories Events which signal changes Waiting for particular events Überblick

254 Example: FileSystemWatcher
Defining event methods Creating FileWatcher and registering event methods Setting filters and waiting for events public static void Changed(object sender, FileSystemEventArgs args) { Console.WriteLine("Changed -> {0}", args.Name); } public static void Created(object sender, FileSystemEventArgs args) {…} public static void Deleted(object sender, FileSystemEventArgs args) {…} public static void Renamed(object sender, RenamedEventArgs args) {…} public static void Main() { FileSystemWatcher fsw = new FileSystemWatcher("c:\\"); fsw.IncludeSubdirectories = true; fsw.Changed += new FileSystemEventHandler(Changed); fsw.Created += new FileSystemEventHandler(Created); fsw.Filter = "*.cs"; while ( ... ) fsw.WaitForChanged(WatcherChangeTypes.All); } Überblick

255 Streaming Framework System.IO contains types for input and output
Base class Stream defines an abstract protocol for byte-oriented input and output Specialization for different media Streams support synchronous and asynchronous protocol Readers and Writers for formatting FileStream MemoryStream NetworkStream CryptoStream BufferedStream Stream Überblick

256 Class Stream Elementary properties of stream
public abstract class Stream : MarshalByRefObject, IDisposable { public abstract bool CanRead { get; } public abstract bool CanSeek { get; } public abstract bool CanWrite { get; } public abstract int Read(out byte[] buff, int offset, int count); public abstract void Write(byte[] buff, int offset, int count); public virtual int ReadByte(); public virtual void WriteByte(byte value); public virtual IAsyncResult BeginRead(…); public virtual IAsyncResult BeginWrite(…); public virtual int EndRead(…); public virtual int EndWrite(…); public abstract long Length { get; } public abstract long Position { get; set; } public abstract long Seek(long offset, SeekOrigin origin); public abstract void Flush(); public virtual void Close(); ... } Elementary properties of stream Synchronous reading and writing Asynchronous reading and writing Length and actual position Positioning Flush and close Überblick

257 Stream Classes Sequential byte streams on various media
long Length long Position bool CanRead bool CanWrite bool CanSeek int Read(byte[] buf, int pos, int len) int ReadByte() Write(byte[] buf, int pos, int len) WriteByte(byte x) long Seek(long pos, SeekOrigin org) SetLength(long len) Flush() Close() Sequential byte streams on various media namespace System.IO FileStream string Name Lock(int pos, int len) Unlock(int pos, int len) MemoryStream int Capacity byte[] GetBuffer() WriteTo(Stream s) NetworkStream bool DataAvailable BufferedStream CryptoStream no Seek Decorators is buffered!

258 Example: FileStream using System; using System.IO; class Test {
static void Copy(string from, string to, int pos) { try { FileStream sin = new FileStream(from, FileMode.Open); FileStream sout = new FileStream(to, FileMode.Create); sin.Seek(pos, SeekOrigin.Begin); // Seek after end of file => pos = end of file int ch = sin.ReadByte(); while (ch >= 0) { sout.WriteByte((byte)ch); ch = sin.ReadByte(); } sin.Close(); sout.Close(); } catch (FileNotFoundException e) { Console.WriteLine("-- file {0} not found", e.FileName); static void Main(string[] arg) { Copy(arg[0], arg[1], 10);

259 Readers and Writers … Readers and Writers overtake formatting tasks
BinaryReader and BinaryWriter for binary data TextReader and TextWriter for character data TextReader StreamReader StringReader TextWriter StreamWriter StringWriter BinaryReader BinaryWriter Stream FileStream MemoryStream NetworkStream Überblick

260 Reader Classes TextReader reads characters
int Read() int ReadBlock(char[] buf, int pos, int len) int Peek() string ReadLine() string ReadToEnd() Close() BinaryReader BinaryReader(Stream s) BinaryReader(Stream s, Encoding e) byte ReadByte() bool ReadBoolean() char ReadChar() short ReadInt16() int ReadInt32() ... Close() StreamReader Stream BaseStream StreamReader(Stream s) StringReader StringReader(string s) TextReader reads characters BinaryReader reads primitive types in binary form Unfortunately, it is not possible to set multiple readers to a stream at the same time. There is no formatted input of numbers, words, etc.

261 Writer Classes Output of data of primitive types in binary form
(TextWriter) string NewLine Write(bool b) Write(char c) Write(int i) ... Write(string format, params object[] arg) WriteLine() WriteLine(bool b) WriteLine(char c) WriteLine(int i) WriteLine(string format, params object[] arg) Flush() Close() BinaryWriter Stream BaseStream BinaryWriter(Stream s) BinaryWriter(Stream s, Encoding e) Write(bool b) Write(char c) Write(int i) ... long Seek(int pos, SeekOrigin org) Flush() Close() Output of data of primitive types in binary form StreamWriter Stream BaseStream StreamWriter(Stream s) StringWriter StringWriter() string ToString() Formatted text output (only sequentially; no Seek)

262 Classes TextReader and TextWriter
public abstract class TextReader : MarshalByRefObject, IDisposable { public virtual int Read(); public virtual int Read(out char[] buf, int idx, int count); public virtual int ReadBlock(out char[] buf, int index, int count); public virtual string ReadLine(); public virtual string ReadToEnd(); public virtual int Peek(); } Different reading operations Writing operations for all the primitive data types Writing operations with line breaks Characters for new line Used encoding public abstract class TextWriter : MarshalByRefObject, IDisposable { public virtual void Write(bool val); public virtual void Write(string s); public virtual void Write(int val); ... // + overloades methods public virtual void WriteLine(); public virtual void WriteLine(bool val); ... // + overloaded methods public virtual string NewLine { get; set; } public abstract Encoding Encoding { get; } } Überblick

263 Input from a File using System; using System.IO; class Test { static void Main() { FileStream s = new FileStream("input.txt", FileMode.Open); StreamReader r = new StreamReader(s); string line = r.ReadLine(); while (line != null) { ... line = r.ReadLine(); } r.Close(); It is not possible to have multiple StreamReaders working on the same stream at the same time.

264 Formatted Output to a File
using System; using System.IO; class Test { static void Main() { FileStream s = new FileStream("output.txt", FileMode.Create); StreamWriter w = new StreamWriter(s); w.WriteLine("Table of sqares:"); for (int i = 0; i < 10; i++) w.WriteLine("{0,3}: {1,5}", i, i*i); w.Close(); } It is not possible to have multiple StreamWriters working on the same stream at the same time.

265 Asynchronous Operations
BeginRead and BeginWrite emit asynchronous read and write operations BeginRead and BeginWrite have AsyncCallback delegate parameter Delegate will be called upon completion of operation with IAsyncResult object public virtual IAsyncResult BeginRead( byte[] buffer, int offset, int count, AsyncCallback callback, object state ); public virtual IAsyncResult BeginWrite( public delegate void AsyncCallback( IAsyncResult ar ); public interface IAsyncResult { object AsyncState {get;} WaitHandle AsyncWaitHandle {get;} bool CompletedSynchronously {get;} bool IsCompleted {get;} ); With EndRead and EndWrite asynchronous operation is completed public virtual int EndRead( IAsyncResult asyncResult ); public virtual void EndWrite( IAsyncResult asyncResult); Überblick

266 Example: Asynchronous Read
Declaring fields for stream, buffer and callback Calling BeginRead of input stream with callback delegate Callback method: Getting number of read bytes by EndRead Processing data namespace AsyncIO { public class AsyncIOTester { private Stream inputStream; private byte[] buffer = new byte[256]; private AsyncCallback callback; public static void Main() { inputStream = File.OpenRead("..."); callback = new AsyncCallback(this.OnCompletedRead) inputStream.BeginRead(buffer, 0, buffer.Length, callback, null); … // continue with some other tasks } void OnCompletedRead(IAsyncResult result) { int bytesRead = inputStream.EndRead(result); … // process the data read } Überblick

267 XML in .NET .NET makes heavy use of XML
see ADO.NET, WSDL, UDDI, SOAP, … The base class library provides implementations for standards like: XML, XSL, XPath, ... Both XML processing models are supported: DOM (Document Object Model) serial access similar to SAX Namespaces System.Xml System.Xml.Xsl System.Xml.XPath System.Xml.Schema System.Xml.Serialization Überblick

268 Processing XML Data XmlReader: Reading XML data
XmlDocument, XmlNode: Object model of XML data (DOM) XmlWriter: Wrting XML data XPathNavigator: XPath selections XslTransform: Transformation of XML documents Überblick

269 XmlReader XmlReader for serial parsing
Similar to SAX, but works with a pull mode Implementations are: XmlTextReader: efficient, no immediate storage of elements XmlValidatingReader: validates document against DTD or XSD XmlNodeReader: reading from an XmlNode (DOM) Überblick

270 Class XmlReader public abstract class XmlReader {
public abstract string Name { get; } public abstract string LocalName { get; } public abstract string Value { get; } public abstract XmlNodeType NodeType { get; } public abstract int AttributeCount { get; } public abstract int Depth { get; } public abstract bool Read(); public virtual string ReadElementString(string name ); public virtual XmlNodeType MoveToContent(); public virtual void Skip(); public abstract string GetAttribute(string name); public abstract void Close(); ... } Properties of current node full name local name value type number of attributes depth in document Reading of next node Get value of next element Move to next element Skipping the current element and its subs Getting the element‘s attributes Closing the reader Überblick

271 Example: XmlTextReader
XmlTextReader r = null; try { r = new XmlTextReader("Addressbook.xml"); r.ReadStartElement("addressbook"); while (r.Read()) { if (r.NodeType == XmlNodeType.Element && r.Name == "person") { int Id = XmlConvert.ToInt32(r.GetAttribute("id")); r.Read(); // Read next node string First = r.ReadElementString("firstname"); string Last = r.ReadElementString("lastname"); r.ReadElementString(" "); // Skip r.ReadEndElement(); // Read </person> Console.WriteLine("{0}: {1}, {2}.", Id, Last, First[0]); } } finally { if (r != null) r.Close(); Output <?xml version='1.0' encoding="utf-8"?> <addressbook owner="1"> <person id="1"> <firstname>Wolfgang</firstname> <lastname>Beer</lastname> </person> <person id="2"> <firstname>Dietrich</firstname> <lastname>Birngruber</lastname> <person id="3"> <firstname>Hanspeter</firstname> <lastname>Moessenboeck</lastname> <person id="4"> <firstname>Albrecht</firstname> <lastname>Woess</lastname> </addressbook> 1: Beer, W. 2: Birngruber, D. 3: Moessenboeck, H. 4: Woess, A. Überblick

272 DOM Construction of object structure in main memory
+ efficient manipulation of XML data size limitations XML elements are represented by XmlElement objects, XML attributes by XmlAttribute objects, etc. (all inherited from XmlNode) XmlDocument object represents whole XML document Example: Loading an XML document: XmlDocument xDoc = new XmlDocument(); xDoc.Load("data.xml"); Überblick

273 Example DOM Document xml addressbook owner person firstname lastname
<?xml version='1.0' encoding="utf-8"?> <addressbook owner="1"> <person id="1"> <firstname>Wolfgang</firstname> <lastname>Beer</lastname> </person> <person id="2"> <firstname>Dietrich</firstname> <lastname>Birngruber</lastname> </addressbook> Document xml addressbook owner person firstname lastname id person firstname lastname id Überblick

274 Class XmlNode (1) Properties of node full name local name type value
public abstract class XmlNode : ICloneable, IEnumerable, IXPathNavigable { public abstract string Name { get; } public abstract string LocalName { get; } public abstract XmlNodeType NodeType { get; } public virtual string Value { get; set; } public virtual XmlAttributeCollection Attributes { get; } public virtual XmlDocument OwnerDocument { get; } public virtual bool IsReadOnly { get; } public virtual bool HasChildNodes { get; } public virtual string Prefix { get; set; } public virtual XmlNodeList ChildNodes { get; } public virtual XmlNode FirstChild { get; } public virtual XmlNode LastChild { get; } public virtual XmlNode NextSibling { get; } public virtual XmlNode PreviousSibling { get; } public virtual XmlNode ParentNode { get; } public virtual XmlElement this[string name] { get; } public virtual XmlElement this[string localname, string ns] { get; } Properties of node full name local name type value attributes Accessing adjacent nodes children siblings parent named subnodes Überblick

275 Class XmlNode (2) Adding and removing nodes Selection of nodes Writing
... public virtual XmlNode AppendChild(XmlNode newChild); public virtual XmlNode PrependChild(XmlNode newChild); public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode refChild); public virtual XmlNode InsertBefore(XmlNode newChild, public virtual XmlNode RemoveChild(XmlNode oldChild); public virtual void RemoveAll(); public XPathNavigator CreateNavigator(); public XmlNodeList SelectNodes(string xpath); public XmlNode SelectSingleNode(string xpath); public abstract void WriteContentTo(XmlWriter w); public abstract void WriteTo(XmlWriter w); } Adding and removing nodes Selection of nodes Writing public enum XmlNodeType { Attribute, CDATA, Comment, Document, DocumentFragment, DocumentType, Element, EndElement, EndEntity, Entity, EntityReference, None, Notation, ProcessingInstruction, SignificantWhitespace, Text, Whitespace, XmlDeclaration } Überblick

276 Class XmlDocument (1) public class XmlDocument : XmlNode {
public XmlDocument(); public XmlElement DocumentElement { get; } public virtual XmlDocumentType DocumentType { get; } public virtual void Load(Stream in); public virtual void Load(string url); public virtual void LoadXml(string data); public virtual void Save(Stream out); public virtual void Save(string url); Root element Document type Loading the XML data Saving Überblick

277 Class XmlDocument (2) public virtual XmlDeclaration CreateXmlDeclaration (string version, string encoding, string standalone); public XmlElement CreateElement(string name); public XmlElement CreateElement (string qualifiedName, string namespaceURI); public virtual XmlElement CreateElement (string prefix, string lName, string nsURI); public virtual XmlText CreateTextNode(string text); public virtual XmlComment CreateComment(string data); Creation of declaration elements text nodes comments Events for changes public event XmlNodeChangedEventHandler NodeChanged; public event XmlNodeChangedEventHandler NodeChanging; public event XmlNodeChangedEventHandler NodeInserted; public event XmlNodeChangedEventHandler NodeInserting; public event XmlNodeChangedEventHandler NodeRemoved; public event XmlNodeChangedEventHandler NodeRemoving; } Überblick

278 Example: Creation of XML Document
XmlDocument enables to built up XML documents Create document and add declaration Create root element Create and add Person element and subelements XmlDocument doc = new XmlDocument(); XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", null, null); doc.AppendChild(decl); XmlElement rootElem = doc.CreateElement("addressbook"); rootElem.SetAttribute("owner", "1"); doc.AppendChild(rootElem); XmlElement person = doc.CreateElement("person"); person.SetAttribute("id", "1"); XmlElement e = doc.CreateElement("firstname"); e.AppendChild(doc.CreateTextNode("Wolfgang")); person.AppendChild(e); e = doc.CreateElement("lastname"); ... <?xml version="1.0" encoding="IBM437"?> <addressbook owner="1"> <person id="1"> <firstname>Wolfgang</firstname> <lastname>Beer</lastname> </person> </addressbook> Überblick

279 XPath XPath is language for identification of elements in an XML document XPath expression (location path) selects a set of nodes A location path consists of location steps, which are separated by "/" //step/step/step/ Examples of location paths are: "*" selects all nodes "/addressbook/*" selects all elements under the addressbook elements "/addressbook/person[1]" returns the first person element of the addressbook elements "/addressbook/*/firstname“ returns the firstname elements under the addressbook Elements Überblick

280 XPathNavigator Class XPathNavigator provides navigation in document
IXPathNavigable (implemented by XmlNode) returns XPathNavigator public abstract class XPathNavigator : ICloneable { public abstract string Name { get; } public abstract string Value { get; } public abstract bool HasAttributes { get; } public abstract bool HasChildren { get; } public virtual XPathNodeIterator Select(string xpath); public virtual XPathNodeIterator Select(XPathExpression expr); public virtual XPathExpression Compile(string xpath); public abstract bool MoveToNext(); public abstract bool MoveToFirstChild(); public abstract bool MoveToParent(); } Properties of current node Selection of nodes by XPath expression Compilation of XPath expression Moving to adjacent nodes public interface IXPathNavigable { XPathNavigator CreateNavigator(); } Überblick

281 Example: XPathNavigator
Load XmlDocument and create XPathNavigator Select firstname elements, iterate over selected elements and put out name values For better run-time efficiency compile expression and use compiled expression XmlDocument doc = new XmlDocument(); doc.Load("addressbook.xml"); XPathNavigator nav = doc.CreateNavigator(); XPathNodeIterator iterator = nav.Select("/addressbook/*/firstname"); while (iterator.MoveNext()) Console.WriteLine(iterator.Current.Value); XPathExpression expr = nav.Compile("/addressbook/person[firstname='Wolfgang']/ "); iterator = nav.Select(expr); while (iterator.MoveNext()) Console.WriteLine(iterator.Current.Value); Überblick

282 XML Transformation with XSL
XSLT is XML language for transformations of XML documents XSL stylesheet is an XML document with a set of rules Rules (templates) define the transformation of XML elements XSLT is based on XPath; XPath expressions define the premises of the rules (match) In the rule body the generation of the transformation result is defined <xsl:stylesheet version="1.0" xmlns:xsl=" <xsl:template match=xpath-expression> construction of transformed elements </xsl:template> </xsl:stylesheet> Überblick

283 Example XSL Stylesheet
<xsl:stylesheet version="1.0" xmlns:xsl=" <xsl:template match="/"> <html> <head> <title>XML Address Book</title> </head> <body> <table border="3" cellspacing="10" cellpadding="5"> <xsl:apply-templates/> </table> </body> </html> </xsl:template> <xsl:template match="addressbook"> <xsl:apply-templates select="person"/> <xsl:template match="person"> <tr> <td> <xsl:value-of select="firstname"/> </td> <td> <b><xsl:value-of select="lastname"/></b> </td> <td> <xsl:value-of select=" "/> </td> </tr> </xsl:stylesheet> Überblick

284 Example Transformation
Original XML document generated HTML document <?xml version='1.0' encoding="utf-8"?> <addressbook owner="1"> <person id="1"> <firstname>Wolfgang</firstname> <lastname>Beer</lastname> </person> <person id="2"> <firstname>Dietrich</firstname> <lastname>Birngruber</lastname> </addressbook> <html> <head> <META http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>XML-AddressBook</title> </head> <body> <table border="3" cellspacing="10" cellpadding="5"> <tr> <td>Wolfgang</td> <td><b>Beer</b></td> </tr> <td>Dietrich</td> <td><b>Birngruber</b></td> </table> </body> </html> Überblick

285 Class XslTransform Namespace System.Xml.Xsl provides support for XSLT
Class XslTransform realizes XSL transformation public class XslTransform { public void Load(string url); public XslTransform(); public void Transform(string infile, string outfile, XmlResolver resolver); ... // + overloaded methodds Load and Transform } Loading an XSLT stylesheet Transformation Überblick

286 Example: Transformation with XSL
XslTransform xt = new XslTransform(); xt.Load("addressbook.xsl"); xt.Transform("addressbook.xml", "addressbook.html"); Überblick

287 Network Communication
Namespace System.Net supports the implementation of typical client/server applications System.Net offers implementation of: Internet protocols, e.g.: TCP, UDP, HTTP; Internet services, e.g.: DNS (Domain Name System) other protocols, e.g.: IrDA System.Net.Sockets offers support for the creation of data streams over networks Überblick

288 Adressing Addressing is done by classes Example:
IPAddress: represents IP address IPEndPoint: represents end point with IP address and port Example: IPAddress ipAdr = new IPAddress(" "); // Create a new IPEndPoint with port number 80 (HTTP) IPEndPoint ep = new IPEndPoint(ipAdr, 80); Überblick

289 DNS (Domain Name System)
DNS offers an IP into domain name mapping service Class Dns supports DNS mapping Class IPHostEntry is container class for address information Example: // Get all the addresses of a given DNS name IPHostEntry host = Dns.Resolve("dotnet.jku.at“); foreach (IPAddress ip in host.AddressList) Console.WriteLine(ip.ToString()); Überblick

290 Sockets Sockets represent bidirectional communication channels, which allow sending and receiving of streamed data Client/server architectures client sends request to the server server handles request and sends back response Addressing by IP addresses and ports Data exchange by streams (see Streaming) Überblick

291 Sockets in .NET (1) Server Client
Create socket and bind it to end point Open socket for maximal 10 clients Client Create socket und end point for client Socket s0 = new Socket(); IPAddress ip = IPAddress.parse(…); IPEndPoint ep = new IPEndPoint(ip,5000); s0.bind(ep); s0.Listen(10); Socket s2 = new Socket(); IPAddress ip = IPAddress.Parse(…); IPEndPoint ep = new IPEndPoint(ip,5000); 5000 s0 Server s2 Client Überblick

292 Sockets in .NET (2) Wait for connection Connect to end point
Socket s1 = s0.Accept(); s2.Connect(ep); 5000 s0 Server s2 Client s1 Communicate with client and disconnect Communicate with server and disconnect s1.Receive(msg1); ... s1.Send(msg2); s1.Shutdown(SocketShutdown.Both); s1.Close(); s2.Send(msg1); ... s2.Receive(msg2); s2.Shutdown(SocketShutdown.Both); s2.Close(); Überblick

293 Example: EchoServer Implements simple client/server application
EchoServer accepts arbitrary data from client and returns them unchanged to client EchoServer EchoClient_1 EchoClient_N Port 5000 „test echo“ „hello“ Überblick

294 Example EchoServer: Class EchoServer (1)
socket s; public bool StartUp(IPAddress ip, int port) { try { s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Bind(new IPEndPoint(ip, port)); s.Listen(10); // maximal 10 clients in queue } catch (Exception e) { ... } for(;;) { Communicate(s.Accept()); // waits for connecting clients } Überblick

295 Example EchoServer: Class EchoServer (2)
... // returns all the received data back to the client public void Communicate(Socket clSock) { try { byte[] buffer = new byte[1024]; while (clSock.Receive(buffer) > 0) // receive data clSock.Send(buffer); // send back the data clSock.Shutdown(SocketShutdown.Both); // close sockets clSock.Close(); } catch (Exception e) { ... } } public static void Main() { EchoServer = new EchoServer(); server.StartUp(IPAddress.Loopback, 5000); // start the echo server Überblick

296 Example EchoServer: Class EchoClient
... public static void Main() { try { // connect to the server Socket s = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Connect(new InetEndPoint(IPAddress.Loopback, 5000)); s.Send( Encoding.ASCII.GetBytes("This is a test“)); // send the message byte[] echo = new byte[1024]; s.Receive(echo); // receive the echo message Console.WriteLine(Encoding.ASCII.GetString(echo)); } catch (Exception e) { ... } } Überblick

297 NetworkStream Socket provides interface for transmitting byte or byte arrays Class NetworkStream provides stream for reading and writing Reader and Writer can be used to read and write complex data structures E.g., XmlTextReader reads data in XML format Überblick

298 Example: NetworkStream and XmlTextReader
Define Socket and connect to end point Create NetworkStream for socket Create XmlTextReader for NetworkStream Read XML data Socket s = new Socket(...); s.Connect( new IPEndPoint(ip, port)); NetworkStream ns = new NetworkStream(s); XmlTextReader r = new XmlTextReader(ns); for (int i = 0; i<r.AttributeCount; i++) { r.MoveToAttribute(); Console.Write(„{0} = {1}“, r.Name, r.Value); } Überblick

299 WebRequest and WebResponse
For getting web resources via standard protocols (HTTP, FTP, …) Abstract classes WebRequest and WebResponse in System.Net namespace Überblick

300 Classes WebRequest and WebResponse
public abstract class WebRequest { public static WebRequest Create(string uri); public static bool RegisterPrefix(string prefix, IWebRequestCreate creator ); public virtual string Method { get; set; } public virtual string ContentType { get; set; } public virtual WebHeaderCollection Headers { get; set; } public virtual Stream GetRequestStream(); public virtual WebResponse GetResponse(); } Creation of Web request with URI Registration of a custom WebRequest implementation HTTP method type (GET or POST) Mime type Headers Stream for writing the request Response object public abstract class WebResponse { public virtual long ContentLength { get; set; } public virtual string ContentType { get; set; } public virtual WebHeaderCollection Headers { get; set; } public virtual Uri ResponseUri { get; } public virtual Stream GetResponseStream(); } Length of response Mime Type Headers URI of response Stream for reading the response Überblick

301 WebRequest/WebResponse Subclasses
WebRequest/WebResponse.Create method creates new instance of one its subclasses depending on the URI: file:// FileWebRequest/FileWebResponse (not in ECMA standard) HttpWebRequest/HttpWebResponse ftp:// FtpWebRequest/FtpWebResponse (only in 2.0) Other URI prefixes can be registered to custom WebRequest/WebResponse implementations via WebRequest.RegisterPrefix method

302 Example: WebRequest and WebResponse
WebRequest req = WebRequest.Create(" if (req is HttpWebRequest) { ((HttpWebRequest) req).UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2;)"; ((HttpWebRequest) req).Credentials = new NetworkCredential("username", "password"); } try { using (WebResponse resp = req.GetResponse()) { foreach (string Key in resp.Headers.Keys) { Console.WriteLine("Header {0}: {1}", Key, resp.Headers[Key]); using (StreamReader sr = new StreamReader(resp.GetResponseStream())) { string Line; while ((Line = sr.ReadLine()) != null) { Console.WriteLine("\t{0}", Line); } catch (WebException ex) { Console.WriteLine(ex.Message); Console.WriteLine("URI: {0}", ex.Response.ResponseUri.ToString()); if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response is HttpWebResponse) { Console.WriteLine("Status code: {0}", ((HttpWebResponse) ex.Response).StatusCode); Überblick

303 WebClient public sealed class WebClient : Component {
public WebClient(); public WebHeaderCollection Headers {get; set;} public ICredentials Credentials {get; set;} public string BaseAddress {get; set;} public WebHeaderCollection ResponseHeaders {get;} public byte[] DownloadData(string address); public void DownloadFile(string address, string fileName); public byte[] UploadData(string address, string method, byte[] data); public byte[] UploadFile(string address, string method, string fileName); public byte[] UploadValues(string address, string method, NameValueCollection data); public Stream OpenRead(string address); public Stream OpenWrite(string address, string method); }

304 Example: WebClient using System.Net;
using System.Collections.Specialized; WebClient wc = new WebClient(); wc.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2;)"); NameValueCollection formValues = new NameValueCollection(); formValues.Add("p", "mbench"); byte[] respBytes = wc.UploadValues(" "POST", formValues); Console.WriteLine("Response headers:"); foreach (string Key in wc.ResponseHeaders.Keys) { Console.WriteLine("\t{0}: {1}", Key, wc.ResponseHeaders.Get(Key)); } Console.WriteLine("Response:"); using (StreamReader sr = new StreamReader(new MemoryStream(respBytes), Encoding.ASCII)) { string Line; while ((Line = sr.ReadLine()) != null) { Console.WriteLine("\t{0}", Line);

305 Sending s System.Web assembly – Microsoft extension (for ASP.NET) Example: using System.Web.Mail; MailMessage m = new MailMessage(); m.From = m.To = m.Subject = “Information"; m.Body = “An important information has been entered in an application.\nYour team"; m.Attachments.Add(new SmtpMail.SmtpServer = "smtp1.ms.mff.cuni.cz"; // optional SmtpMail.Send(m);

306 High Level Communication Options
XML Web Services Are ASP.NET applications Hosted in IIS (Internet Information Services) – ASP.NET is ISAPI filter (as of Windows 2000, XP) Via HTTP & SOAP Easy metadata access (can be downloaded as WSDL schema) .NET Remoting Hosted in any application (Windows Service, console application, etc.) SOAP, binary protocols (or user defined) Control activation characterictics and object lifetime

307 Remotable vs. Nonremotable
Nonremotable objects Do not provide any way to copied to or represented in another application Basically all objects that are not remotable Remotable objects Marshal-By-Value Objects Marshal-By-Reference Objects

308 Marshal-By-Value Objects
Must be serializable Must have SerializableAttribute defined All public and private member fields are serialized – this implies that all of them must be serializable, i.e. have SerializableAttribute defined Fields with NonSerializedAttribute are excluded from default serialization Can implement ISerializable interface to provide their own serialization Serialized to stream on server side and send to client Deserialized into new local instance on client side No calls passed to server NET 1.1: Automatic deserialization is not allowed BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider(); provider.TypeFilterLevel = TypeFilterLevel.Full; IDictionary props = new Hashtable(); props["port"] = 8085; TcpChannel chan = new TcpChannel(props, null, provider);

309 Serialization and Formatters
namespace System.Runtime.Serialization.Formatters.Binary BinaryFormatter namespace System.Runtime.Serialization.Formatters.Soap SoapFormatter public interface IFormatter { void Serialize(Stream serializationStream, object graph); object Deserialize(Stream serializationStream); } Serializes graph into a stream Creates new instance of an object according to serialization data stored in a stream

310 Example Serialization
[Serializable()] public class TestSimpleObject { public int member1; public string member2; public string member3; public double member4; [NonSerialized()] public string member5; public TestSimpleObject() member1 = 11; member2 = "hello"; member3 = "hello"; member4 = ; member5 = "hello world!"; } public void Print() Console.WriteLine("member1 = '{0}'", member1); Console.WriteLine("member2 = '{0}'", member2); Console.WriteLine("member3 = '{0}'", member3); Console.WriteLine("member4 = '{0}'", member4); Console.WriteLine("member5 = '{0}'", member5);

311 Example Serialization, cont.
using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Soap; public class Test { public static void Main() TestSimpleObject obj = new TestSimpleObject(); obj.Print(); Stream stream = File.Open("data.xml", FileMode.Create); SoapFormatter formatter = new SoapFormatter(); formatter.Serialize(stream, obj); stream.Close(); obj = null; stream = File.Open("data.xml", FileMode.Open); obj = (TestSimpleObject) formatter.Deserialize(stream); }

312 Example Serialization, cont.
Output “data.xml”: <SOAP-ENV:Envelope …> <SOAP-ENV:Body> <a1:TestSimpleObject id="ref-1" xmlns:a1=" <member1>11</member1> <member2 id="ref-3">hello</member2> <member3 href="#ref-3"/> <member4> </member4> </a1:TestSimpleObject> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

313 Marshal-By-Reference Objects Overview
Must extend System.MarshalByRefObject class References are represented by ObjRef class (when an object is marshaled) – itself serializable Contains information about type and location (identified by URL) Proxy is created on client side – redirects calls to server Reference to remote object is got by new (needs to be preconfigured) or by System.Activator methods

314 Marshal-By-Reference Objects Activation
Server-activated objects Client proxy is created by calling new or Activator.GetObject() Creation of server instance is controlled by server Can be: Dynamically marshaled (activated independently on client requests) Singleton Single Call Client-activated objects Both client proxy and server instance are created when client calls new or Activator.CreateInstance()

315 Marshal-By-Reference Objects Activation
public class RemotingConfiguration { public static void Configure(string filename); public static void RegisterActivatedServiceType( Type type ); public static void RegisterActivatedClientType( Type type, string appUrl public static void RegisterWellKnownServiceType( string objectUri, WellKnownObjectMode mode public static void RegisterWellKnownClientType( string objectUrl } Reads Remoting configuration from a XML file Server: register client-activated class Client: register remote client-activated class Server: register server-activated class WellKnownObjectMode.SingleCall WellKnownObjectMode.Singleton Client: register remote server-activated class

316 Request/Reply Transport
In messages Messages are transported through Channels: HttpChannel TcpChannel IpcChannel (in .NET 2.0) Messages are created from requests by Formatters: SoapFormatter BinaryFormatter Messages, Channels, Formatters, etc. are classes – new ones can be created to implement user specific transports and protocols

317 Server-activated Objects Client/Server Example ServiceClass.cs
using System; using System.Diagnostics; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; public class ServiceClass : MarshalByRefObject { private DateTime starttime; public ServiceClass(){ Console.WriteLine("A ServiceClass has been created."); starttime = DateTime.Now; } ~ServiceClass(){ Console.WriteLine("ServiceClass being collected after " + (new TimeSpan(DateTime.Now.Ticks - starttime.Ticks)).ToString() + " seconds."); public DateTime GetServerTime(){ Console.WriteLine("Time requested by client."); return DateTime.Now;

318 Server-activated Objects Dynamic marshaling Server.cs
using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Remoting.Services; public class ServerProcess{ public static void Main(string[] Args){ TcpChannel channel = new TcpChannel(8080); ChannelServices.RegisterChannel(channel); ServiceClass service = new ServiceClass(); ObjRef obj = RemotingServices.Marshal(service, "TcpService"); Console.WriteLine("Press Enter to disconnect the object."); Console.ReadLine(); RemotingServices.Disconnect(service); }

319 Server-activated Objects Client.cs #1
using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; public class ClientProcess{ public static void Main(string[] Args){ ChannelServices.RegisterChannel(new TcpChannel()); ServiceClass service = (ServiceClass) Activator.GetObject( typeof(ServiceClass), "tcp://localhost:8080/TcpService“ ); Console.WriteLine("Server time: " + service.GetServerTime().ToLongTimeString()); }

320 Server-activated Objects Client.cs #2
using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; public class ClientProcess{ public static void Main(string[] Args){ ChannelServices.RegisterChannel(new TcpChannel()); WellKnownClientTypeEntry remotetype = new WellKnownClientTypeEntry( typeof(ServiceClass), "tcp://localhost:8080/TcpService“ ); RemotingConfiguration.RegisterWellKnownClientType(remotetype); ServiceClass service = new ServiceClass(); Console.WriteLine("Server time: " + service.GetServerTime().ToLongTimeString()); }

321 Server-activated Objects Singleton/SingleCall server
using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using System.Runtime.Remoting.Services; public class ServerProcess{ public static void Main(string[] Args){ TcpChannel channel = new TcpChannel(8080); ChannelServices.RegisterChannel(channel); RemotingConfiguration.RegisterWellKnownServiceType( typeof(ServiceClass), “TcpService", WellKnownObjectMode.Singleton ); Console.WriteLine("Press Enter to exit."); Console.ReadLine(); }

322 Marshal-By-Reference Objects Lifetime
Lifetime is NOT controlled by reference counting, but lifetime leases are used When creating object its new lease is created Managed by Lease Manager Lease has list of its sponsors – they are asked to renew lease Lease properties – can be changed only during init of lease: InitialLeaseTime (5 minutes) – can be infinite CurrentLeaseTime RenewOnCallTime (2 minutes) SponsorshipTimeout (2 minutes) LeaseManagerPollTime (10 seconds) List of sponsors is empty -> prepared for GC To define custom lease properties MarshalByRefObject.InitializeLifetimeService needs to be overriden (can return null reference to ILease).

323 Marshal-By-Reference Objects Lifetime – Lease renewal
Client can get lease of remote object and explicitly require lease renewal RemoteType obj = new RemoteType(); ILease lease = (ILease) RemotingServices.GetLifetimeService(obj); TimeSpan expireTime = lease.Renew(TimeSpan.FromSeconds(20));

324 Chat Example ChatCoordinator.cs
using System; using System.Runtime.Remoting; using System.Collections; [Serializable] public class SubmitEventArgs : EventArgs { private string _string = null; private string _alias = null; public SubmitEventArgs(string contribution, string contributor) { this._string = contribution; this._alias = contributor; } public string Contribution{ get{ return _string; public string Contributor{ get { return _alias;

325 Chat Example ChatCoordinator.cs, cont.
public delegate void SubmissionEventHandler(object sender, SubmitEventArgs submitArgs); public class ChatCoordinator : MarshalByRefObject { public ChatCoordinator(){ Console.WriteLine("ChatCoordinator created."); } public override object InitializeLifetimeService(){ return null; public event SubmissionEventHandler Submission; public void Submit(string contribution, string contributor){ Console.WriteLine("{0} sent: {1}.", contributor, contribution); SubmitEventArgs e = new SubmitEventArgs(contribution, contributor); if (Submission != null){ Console.WriteLine("Broadcasting..."); Submission(this, e);

326 Chat Example ChatCentral.cs
using System; using System.Runtime.Remoting; public class ServerProcess{ // This simply keeps the ChatCoordinator application domain alive. public static void Main(string[] Args){ RemotingConfiguration.Configure("ChatCentral.exe.config"); Console.WriteLine("The host application is running. Press Enter to stop."); Console.ReadLine(); }

327 Chat Example ChatClient.cs
using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; public class ChatClient : MarshalByRefObject { private string _alias = null; public override object InitializeLifetimeService() { return null; } public ChatClient(string alias){ this._alias = alias; public static void Main(string[] Args){ if (Args.Length != 1){ Console.WriteLine("You need to type an alias."); return; } ChatClient client = new ChatClient(Args[0]); client.Run();

328 Chat Example ChatClient.cs, cont.
public void Run(){ RemotingConfiguration.Configure("ChatClient.exe.config"); // Create a proxy to the remote object. ChatCoordinator chatcenter = new ChatCoordinator(); chatcenter.Submission += new SubmissionEventHandler(this.SubmissionReceiver); String keyState = ""; while (true){ Console.WriteLine("Press 0 (zero) and ENTER to Exit:\r\n"); keyState = Console.ReadLine(); if (String.Compare(keyState,"0", true) == 0) break; chatcenter.Submit(keyState, _alias); } chatcenter.Submission -= new SubmissionEventHandler(this.SubmissionReceiver); public void SubmissionReceiver(object sender, SubmitEventArgs args){ if (String.Compare(args.Contributor, _alias, true) == 0){ Console.WriteLine("Your message was broadcast."); } else Console.WriteLine(args.Contributor + " says: " + args.Contribution);

329 Chat Example ChatCentral.exe.config
<configuration> <system.runtime.remoting> <application> <service> <wellknown mode="Singleton" type="ChatCoordinator, ChatCoordinator" objectUri="Chat" /> </service> <channels> <channel ref=“http" port="8080" </channels> </application> </system.runtime.remoting> </configuration>

330 Chat Example ChatClient.exe.config
<configuration> <system.runtime.remoting> <application> <client> <wellknown type="ChatCoordinator, ChatCoordinator" url=“ /> </client> <channels> <channel ref=“http" port="0" </channels> </application> </system.runtime.remoting> </configuration>

331 Chat Example Machine.config
Default location: %SystemRoot%\Microsoft .NET\Framework\<version>\Config <configuration> <system.runtime.remoting> <channels> <channel id="http" type="System.Runtime.Remoting.Channels.Http.HttpChannel, System.Runtime.Remoting, Version= , Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <channel id="tcp" type="System.Runtime.Remoting.Channels.Tcp.TcpChannel, System.Runtime.Remoting, Version= , Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </channels> </system.runtime.remoting> </configuration>

332 Outline - LS ADO.NET Web Services WinForms C# 3.0 Managed C++, C++/CLI
Appdomains & assembly loading Inside .NET objects, strings and arrays Garbage Collector ? Security ? ? ASP.NET ? ? COM Interop ?

333 Thursday, 15:40, SW2 Tomáš Matoušek
CLI implementations Rotor (SSCLI) and Mono Run-time internals assembly binding, type loading generics native/managed code interop just-in-time compiler Compiler related compiler tools (Bison equivalents on .NET) API for metadata reading and generation IL assembler, emitting IL code Lightweight Code Generation (LCG) CLR hosting (SQL server, Internet Explorer) How to write .NET debugger .NET profiler Visual Studio Integration package How tools work NGEN MSBuild Überblick

334 ADO.NET Introduction Connection-oriented Access Connectionless Access
Database Access with DataAdapter Integration with XML ADO.NET 2.0 Summary Überblick

335 ADO.NET Is the .NET technology for accessing structured data
Uniform object oriented interface for different data sources relational data bases XML data other data sources Designed for distributed and Web applications Provides 2 models for data access connection-oriented connectionless Überblick

336 Idea of Universal Data Access
Connection of (object-oriented) programming languages and relational data bases Uniform programming model and API Special implementations for data sources (providers) MsSql DB2 Oracle Application ? provider ODBC API Überblick

337 Data Providers Microsoft’s layered architecture for data access
ADO.NET SQL Server Oracle MySQL ODBC OLEDB SQL-data Non-SQL-data MS SQL Server, Oracle, Jet, Foxpro, ... Directory Services, Mail, Text, Video, ... Überblick

338 History of Universal Data Access (Microsoft)
ODBC OLE DB ADO (ActiveX Data Objects) ADO.NET ADO ADO.NET connection-oriented connection-oriented + connectionless sequential access sequential access + main-memory representation with direct access only one table supported more than one table supported COM-marshalling XML-marshalling Überblick

339 Architecture of ADO.NET
connectionless connection-oriented Überblick

340 Connection-oriented versus Connectionless
Keeps the connection to the data base alive Always up-to-date data Intended for applications with: short running transactions only a few parallel access operations Connectionless No permanent connection to the data source Data cached in main memory Changes in main memory may be in conflict with changes in data source many parallel and long lasting access operations (e.g.: Web applications) Überblick

341 ADO.NET Assembly and Namespaces
System.Data.dll Namespaces: System.Data general types System.Data.Common classes for implementing providers System.Data.OleDb OLE DB provider System.Data.SqlClient Microsoft SQL Server provider System.Data.SqlTypes data types for SQL Server System.Data.Odbc ODBC provider (since .NET 1.1) System.Data.OracleClient Oracle provider (since .NET 1.1) System.Data.SqlServerCe Compact Framework Überblick

342 ADO.NET Introduction Connection-oriented Access Connectionless Access
Database Access with DataAdapter Integration with XML ADO.NET 2.0 Summary Überblick

343 Architecture DbConnection DbCommand DbTransaction DataReader
represents connection to data source DbCommand represents a SQL command DbTransaction represents a transaction commands can be executed within a transaction DataReader result of a data base query allows sequential reading of rows Überblick

344 Class Hierarchy General interface definitions Special implementations
IDbConnection IDbCommand IDbTransaction IDataReader Special implementations OleDb: implementation for OLEDB Sql: implementation for SQL Server Oracle: implementation for Oracle Odbc: implementation for ODBC SqlCe: implementation for SQL Server CE data base Überblick

345 Example: Northwind Database
Microsoft Example for SQL Server Reading of table Employees Output of EmployeeID, LastName, FirstName for all rows of table Employees Run Überblick

346 Program Pattern for Connection-oriented Data Access
1.) Declare connection try { 1.) Request connection to database 2.) Execute SQL commands 3.) Process result 4.) Release Resources } catch ( Exception ) { Handle exception } finally { try { 4.) Close connection } catch (Exception) { Handle exception } } Überblick

347 Example: EmployeeReader (1)
using System; using System.Data; using System.Data.OleDb; public class EmployeeReader { public static void Main() { string connStr = "provider=SQLOLEDB; data source=(local)\\NetSDK; " + "initial catalog=Northwind; user id=sa; password=; "; IDbConnection con = null; // declare connection object try { con = new OleDbConnection(connStr); // create connection object con.Open(); // open connection 1) Declare and request connection to database //----- create SQL command IDbCommand cmd = con.CreateCommand(); cmd.CommandText = "SELECT EmployeeID, LastName, FirstName FROM Employees"; //----- execute SQL command; result is an OleDbDataReader IDataReader reader = cmd.ExecuteReader(); 2) Execute SQL commands // continue next page Überblick

348 Example: EmployeeReader (2)
IDataReader reader = cmd.ExecuteReader(); object[] dataRow = new object[reader.FieldCount]; while (reader.Read()) { int cols = reader.GetValues(dataRow); for (int i = 0; i < cols; i++) Console.Write("| {0} " , dataRow[i]); Console.WriteLine(); } 3) Read and process data rows //----- close reader reader.Close(); } catch (Exception e) { Console.WriteLine(e.Message); } finally { try { if (con != null) // close connection con.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } 4) Release resources and close connection Überblick

349 Interface IDbConnection
ConnectionString defines data base connection Open and close connection Properties of connection object Creates Command-Object Creates Transaction-Object string ConnectionString {get; set;} void Open(); void Close(); string Database {get;} int ConnectionTimeout {get;} ConnectionState State {get;} IDbCommand CreateCommand(); IDbTransaction BeginTransaction(); IDbTransaction BeginTransaction(IsolationLevel lvl); Überblick

350 IDbConnection: Property ConnectionString
Key-value-pairs separated by semicolon (;) Configuration of the connection name of the provider identification of data source authentication of user other database-specific settings e.g.: OLEDB: "provider=SQLOLEDB; data source= \\NetSDK; initial catalog=Northwind; user id=sa; password=; " "provider=Microsoft.Jet.OLEDB.4.0;data source=c:\bin\LocalAccess40.mdb;" "provider=MSDAORA; data source=ORACLE8i7; user id=OLEDB; password=OLEDB;“ e.g.: MS-SQL-Server: "data source=(local)\\NetSDK; initial catalog=Northwind; user id=sa; pooling=false; Integrated Security=SSPI; connection timout=20;" SqlServer Access Oracle Überblick

351 Command Objects IDbTransaction 0..1 * IDbCommand IDataParameter * 1 IDbConnection 1 Command objects define SQL statements or stored procedures Executed for a connection May have parameters May belong to a transaction Überblick

352 Interface IDbCommand CommandText defines SQL statement or stored procedure Connection object Type and timeout properties Creating and accessing parameters Execution of command string CommandText {get; set;} IDbConnection Connection {get; set;} CommandType CommandType {get; set;} int CommandTimeout {get; set;} IDbDataParameter CreateParameter(); IDataParameterCollection Parameters {get;} IDataReader ExecuteReader(); IDataReader ExecuteReader(CommandBehavior b); int ExecuteNonQuery(); object ExecuteScalar(); Überblick

353 ExecuteReader Method IDataReader ExecuteReader() IDataReader ExecuteReader( CommandBehavior behavior ); public enum CommandBehavior { CloseConnection, Default, KeyInfo, SchemaOnly, SequentialAccess, SingleResult, SingleRow } Executes the data base query specified in CommandText Result is an IDataReader object Example: cmd.CommandText = "SELECT EmployeeID, LastName, FirstName FROM Employees "; IDataReader reader = cmd.ExecuteReader(); Überblick

354 ExecuteNonQuery Method
int ExecuteNonQuery(); Executes the non-query operation specified in CommandText UPDATE INSERT DELETE CREATE TABLE Result is number of affected rows Example: cmd.CommandText = "UPDATE Empls SET City = ’Seattle’ WHERE iD=8"; int affectedRows = cmd.ExecuteNonQuery(); Überblick

355 ExecuteScalar Method object ExecuteScalar(); Returns the value of the 1st column of the 1st row delivered by the query CommandText typically is an aggregate function Example: cmd.CommandText = " SELECT count(*) FROM Employees "; int count = (int) cmd.ExecuteScalar(); Überblick

356 Parameters Command objects allow input and output parameters
Parameter objects specify Name: name of the parameter Value: value of the parameter DbDataType: data type of the parameter Direction: direction of the parameter Input Output InputOutput ReturnValue IDataParameterCollection Parameters {get;} Überblick

357 Working with Parameters
1. Define SQL command with place holders OLEDB: Identification of parameters by position (notation: "?") SQL Server: Identification of parameters by name (notation: OleDbCommand cmd = new OleDbCommand(); cmd.CommandText = "DELETE FROM Empls WHERE EmployeeID = ?"; SqlCommand cmd = new SqlCommand(); cmd.CommandText = "DELETE FROM Empls WHERE EmployeeID 2. Create and add parameter cmd.Parameters.Add( new OleDbType.BigInt)); 3. Assign values and execute command = 1234; cmd.ExecuteNonQuery(); Überblick

358 Transactions ADO.NET supports transactions
Commands can be executed within transactions Execution of commands are committed with Commit aborted with Rollback Überblick

359 Working with Transactions (1)
1. Define connection and create Transaction object SqlConnection con = new SqlConnection(connStr); IDbTranaction trans = null; try { con.Open(); trans = con.BeginTransaction(); 2. Create Command object, assign it to Transaction object, and execute it IDbCommand cmd1 = con.CreateCommand(); cmd1.CommandText = "DELETE [OrderDetails] WHERE OrderId = 10258"; cmd1.Transaction = trans; cmd1.ExecuteNonQuery(); IDbCommand cmd2 = con.CreateCommand(); cmd2.CommandText = "DELETE Orders WHERE OrderId = 10258"; cmd2.Transaction = trans; cmd2.ExecuteNonQuery(); Überblick

360 Working with Transactions (2)
3. Commit or abort transaction trans.Commit(); catch (Exception e) { if (trans != null) trans.Rollback(); } finally { try { con.Close(); } Überblick

361 DataReader ExecuteReader() returns IDataReader object
IDataReader allows sequential reading of result (row by row) IDataReader ExecuteReader() IDataReader ExecuteReader( CommandBehavior behavior ); Überblick

362 Interface IDataReader
Read reads next row Access column values using indexers Typed access of column values using access methods Getting meta-information bool Read(); object this[int] {get;} object this[string] {get;} bool GetBoolean(int idx); byte GetByte(int idx); ... string GetDataTypeName(int i); string GetName(int idx); int GetOrdinal(string name); ... Überblick

363 Working with IDataReader
IDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { Create IDataReader object and read rows object[ ] dataRow = new object[reader.FieldCount]; int cols = reader.GetValues(dataRow); Read column values into an array object val0 = reader[0]; object nameVal = reader["LastName"]; Read column values using indexers string firstName = reader.getString(2); Read column value using typed access method getString } reader.Close(); Close IDataReader object Überblick

364 ADO.NET Introduction Connection-oriented Access Connectionless Access
Database Access with DataAdapter Integration with XML ADO.NET 2.0 Summary Überblick

365 Motivation and Idea Motivation Idea  “main memory data base“
Many parallel, long lasting access operations Connection-oriented data access too costly Idea Caching data in main memory  “main memory data base“ Only short connections for reading and updates  DataAdapter Main memory data base independent from data source conflicting changes are possible Überblick

366 ADO.NET Technology Chain
Data store DataSet DataSet DataAdapter Conn ection XML DataGrid DataView Überblick

367 Architecture of Connectionless Data Access
connection-oriented Überblick

368 DataSet Structure DataTable .Columns[..] .Rows[..] DataView
.Tables[...] .Relations[...] ... DataTable .Columns[..] .Rows[..] .Columns[...] .Rows[...] .DefaultView ... DataColumn schema DataRow data DataView DataRelation Überblick

369 DataSet Main memory data base DataSet consists of
relational structure object oriented interface DataSet consists of collection of DataTables collection of DataRelations DataTables consists of collection of DataTableColumns (= schema definition) collection of DataTableRows (= data) DefaultView (DataTableView, see later) DataRelations associate two DataTable objects define ParentTable and ParentColumns and ChildTable and ChildColumns Überblick

370 DataSet Class Diagram Überblick

371 Example: Person Contacts
Implementation steps: Define schema Define data Access data Überblick

372 Person Contacts: Define Schema (1)
DataSet ds = new DataSet("PersonContacts"); DataTable personTable = new DataTable("Person"); Create DataSet and DataTable "Person" DataColumn col = new DataColumn(); col.DataType = typeof(System.Int64); col.ColumnName = "ID"; col.ReadOnly = true; col.Unique = true; // values must be unique col.AutoIncrement = true; // keys are assigned automatically col.AutoIncrementSeed = -1; // first key starts with -1 col.AutoIncrementStep = -1; // next key = prev. key - 1 Define column "ID" and set properties personTable.Columns.Add(col); personTable.PrimaryKey = new DataColumn[ ] { col }; Add column to table and set as primary key Überblick

373 Person Contacts: Define Schema (2)
col = new DataColumn(); col.DataType = typeof(string); col.ColumnName = "FirstName"; personTable.Columns.Add(col); Define and add column "FirstName" col = new DataColumn(); col.DataType = typeof(string); col.ColumnName = "Name"; personTable.Columns.Add(col); Define and add column "Name" ds.Tables.Add(personTable); Add table to DataSet DataTable contactTable = new DataTable("Contact"); ... ds.Tables.Add(contactTable); Create table "Contact" in similar way Überblick

374 Person Contacts: Define Relation
Create relation PersonHasContacts and add it to the DataSet DataColumn parentCol = ds.Tables["Person"].Columns["ID"]; DataColumn childCol = ds.Tables["Contact"].Columns["PersonID"]; DataRelation rel = new DataRelation("PersonHasContacts", parentCol, childCol); ds.Relations.Add(rel); Überblick

375 Person Contacts: Define Data Rows
DataRow personRow = personTable.NewRow(); personRow[1] = "Wolfgang"; personRow["Name"] = "Beer"; Create new row and assign column values Add row to table "Person" personTable.Rows.Add(row); Create and add row to table "Contact" DataRow contactRow = contactTable.NewRow (); contactRow[0] = "Wolfgang"; ... contactRow["PersonID"] = (long)personRow["ID"]; // defines relation contactTable.Rows.Add (row); Commit changes ds.AcceptChanges(); Überblick

376 Person Contacts: Access Data
foreach (DataRow person in personTable.Rows) { Console.WriteLine("Contacts of {0}:", person["Name"]); Iterate over all persons of personTable and put out the names Access contacts through relation "PersonHasContacts" and print out contacts foreach (DataRow contact in person.GetChildRows("PersonHasContacts")) { Console.WriteLine("{0}, {1}: {2}", contact[0], contact["Name"], contact["Phone"] ); } Überblick

377 DataSet: Change Management
DataSets maintain all changes Changes are accepted with acceptChanges or discarded with rejectChanges ... if (ds.HasErrors) { ds.RejectChanges(); } else { ds.AcceptChanges(); } Überblick

378 DataRowVersion DataSets store different versions of data row values:
Current: current values Original: original values Proposed: proposed values (values which are currently processed) Default: standard, based on DataRowState public enum DataRowVersion { Current, Original, Proposed, Default } DataRowState Default Added, Modified, Unchanged Current Deleted Original Detached Proposed Example: bool hasOriginal = personRow.HasVersion(DataRowVersion.Original); if (hasOriginal) { string originalName = personRow["Name", DataRowVersion.Original]; } Überblick

379 State Diagram of a DataRow object
DataRow objects have different states public DataRowState RowState {get;} public enum DataRowState { Added, Deleted, Detached, Modified, Unchanged } Detached row=table.NewRow Accept- Changes table.Row. Remove(row) row. Delete Added table.Row. Add(row) Reject- Changes Modified row[…] = … Reject- Changes Unchanged Accept- Changes Accept- Changes Deleted row.Delete row.Delete RejectChanges Überblick

380 Exception Handling ADO.NET checks validity of operations on DataSets
and throws DataExceptions DataException ConstraintException DeletedRowInaccessibleExcception DuplicateNameException InvalidConstraintException InvalidExpressionException MissingPrimaryKeyException NoNullAllowedException ReadOnlyException RowNotInTableException ... Überblick

381 DataView DataViews support views of tables DataView supports
RowFilter: Filtering based on filter expression RowStateFilter: Filtering based on row states Sort: Sorting based on columns DataView supports changing data rows fast search (based on sorted columns) DataView objects can be displayed by GUI elements e.g. DataGrid Überblick

382 Working with DataView DataView a_kView = new DataView(personTable); dataView.RowFilter = "FirstName <= 'K'"; dataView.RowStateFilter = DataViewRowState.Added | DataViewRowState.ModifiedCurrent; dataView.Sort = "Name ASC"; // sort by Name in ascending order Create DataView object and set filter and sorting criteria Display data in DataGrid DataGrid grid = new DataGrid(); ... grid.DataSource = dataView; Fast search for row based on "Name" column int i = dataView.Find("Beer"); grid.Select(i); Überblick

383 ADO.NET Introduction Connection-oriented Access Connectionless Access
Database Access with DataAdapter Integration with XML ADO.NET 2.0 Summary Überblick

384 Architecture connectionless connection-oriented
DataAdapter for connection to data source Fill: Filling the DataSet Update: Writing back changes DataAdapters use Command objects SelectCommand InsertCommand DeleteCommand UpdateCommand connectionless connection-oriented Überblick

385 DataAdapter Class Diagram
Überblick

386 DataAdapter: Loading Data
IDbDataAdapter adapter = new OleDbDataAdapter(); OleDbCommand cmd = new OleDbCommand(); cmd.Connection = new OleDbConnection ("provider=SQLOLEDB; ..." ); cmd.CommandText = "SELECT * FROM Person"; adapter.SelectCommand = cmd; Create DataAdapter object and set SelectCommand Read data from data source and fill DataTable "Person" adapter.Fill(ds, "Person"); Only works when DataTable „Person“ already exists! And is compatible to database table! Accept or discard changes Delete DataAdapter object if (ds.HasErrors) ds.RejectChanges(); else ds.AcceptChanges(); if (adapter is IDisposable) ((IDisposable)adapter).Dispose(); Überblick

387 DataAdapter: Loading Schema and Data
IDbDataAdapter adapter = new OleDbDataAdapter(); OleDbCommand cmd = new OleDbCommand(); cmd.Connection = new OleDbConnection ("provider=SQLOLEDB; ..." ); cmd.CommandText = "SELECT * FROM Person; SELECT * FROM Contact"; adapter.SelectCommand = cmd; Create DataAdapter object and set SelectCommand Define action for missing schema and mapping to tables adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; adapter.TableMappings.Add("Table", "Person"); adapter.TableMappings.Add("Table1", "Contact"); Add AddWithKey Error Ignore Read data from data source and fill DataTable "Person" adapter.Fill(ds); Accept or discard changes; delete DataAdapter object if (ds.HasErrors) ds.RejectChanges(); else ds.AcceptChanges(); if (adapter is IDisposable) ((IDisposable)adapter).Dispose(); Überblick

388 DataAdapter: Writing Back Changes (1)
Changes are written back with Update method Update-, Insert- and DeleteCommand define how changes are written CommandBuilder can create Update-, Insert- und DeleteCommand from SelectCommand automatically (in simple cases ) Conflict management for updates: comparison of data in DataTable and data source in case of conflict DBConcurrencyException is thrown Überblick

389 DataAdapter: Writing Back Changes (2)
OleDbConnection con = new OleDbConnection ("provider=SQLOLEDB; …"); adapter = new OleDbDataAdapter("SELECT * FROM Person", con); Create DataAdapter with SELECT expression Create update commands using CommandBuilder OleDbCommandBuilder cmdBuilder = new OleDbCommandBuilder(adapter); Call Update and handle conflicts try { adapter.Update(ds, tableName); } catch (DBConcurrencyException) { // Handle the error, e.g. by reloading the DataSet } adapter.Dispose(); Überblick

390 DataAdapter: Event Handling
Two events signaled on updates for each data row OnRowUpdating: just before updating the data source OnRowUpdated: just after updating the data source public sealed class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter { public event OleDbRowUpdatingEventHandler RowUpdating; public event OleDbRowUpdatedEventHandler RowUpdated; } public delegate void OleDbRowUpdatedEventHandler( object sender, OleDbRowUpdatedEventArgs e ); public sealed class OleDbRowUpdatedEventArgs : RowUpdatedEventArgs { public DataRow Row {get;} public StatementType StatementType {get;} public UpdateStatus Status {get; set;} } Überblick

391 DataAdapter: Event Handling Example
Define handler methods private void onRowUpdating(object sender, OleDbRowUpdatedEventArgs args) { Console.WriteLn("Updating row for {0}", args.Row[1]); ... } private void onRowUpdated(object sender, OleDbRowUpdatedEventArgs args) { OleDbDataAdapter adapter = new OleDbDataAdapter(); ... da.RowUpdating += new OleDbRowUpdatingEventHandler(this.OnRowUpdating); da.RowUpdated += new OleDbRowUpdatingEventHandler(this.OnRowUpdated); Add delegates to events of DataAdapter Überblick

392 ADO.NET Introduction Connection-oriented Access Connectionless Access
Database Access with DataAdapter Integration with XML ADO.NET 2.0 Summary Überblick

393 Integration DataSets und XML
DataSets and XML are highly integrated serializing DataSets as XML documents XML documents as data sources for DataSets schemas for DataSets defined as XML schemas strongly typed DataSets generated from XML schemas access to DataSets using XML-DOM interface Integration of DataSets and XML used in distributed systems, e.g., Web Services (see Microsoft 3-Tier Architecture) Überblick

394 Writing and Reading XML Data
Methods for writing and reading XML data public class DataSet : MarshalByValueComponent, IListSource, ISupportInitialize, ISerializable { public void WriteXml( Stream stream ); public void WriteXml( string fileName ); public void WriteXml( TextWriter writer); public void WriteXml( XmlWriter writer ); public void WriteXml( Stream stream, XmlWriteMode m ); public XmlReadMode ReadXml ( Stream stream ); public XmlReadMode ReadXml ( string fileName ); public XmlReadMode ReadXml ( TextWriter writer); public XmlReadMode ReadXml ( XmlWriter writer ); public XmlReadMode ReadXml ( Stream stream, XmlReadMode m ); ... } public enum XmlWriteMode {DiffGram, IgnoreSchema, WriteSchema} public enum XmlReadMode { Auto, DiffGram, IgnoreSchema, ReadSchema, InferSchema, Fragment } Überblick

395 Example: Writing and Reading XML Data
<?xml version="1.0" standalone="yes" ?> <PersonContacts> - <Person>   <ID>1</ID>   <FirstName>Wolfgang</FirstName>   <Name>Beer</Name> </Person>   <ID>2</ID>   <FirstName>Dietrich</FirstName>   <Name>Birngruber</Name>   </Person> <Contact> <ID>1</ID>   <NickName>Didi</NickName>     <Phone>7133</Phone>   <PersonID>2</PersonID>   </Contact> - <Contact> ...   <PersonID>1</PersonID>   </PersonContacts> ds.writeXML("personcontact.xml"); Write data to XML file DataSet ds = new DataSet(); ds.readXML("personcontact.xml", XmlReadMode.Auto); Read data from XML with XmlReadMode.Auto a schema is generated automatically Überblick

396 DataSet and XML Schema DataSets allow reading and writing XML schemas
WriteXmlSchema: Writes XML schema ReadXmlSchema: Reads XML schema and constructs DataSet InferXmlSchema: Reads XML data and infers schema from data ... public void WriteXmlSchema ( Stream stream ); public void WriteXmlSchema ( string fileName ); public void WriteXmlSchema ( TextWriter writer); public void WriteXmlSchema ( XmlWriter writer ); public void ReadXmlSchema ( Stream stream ); public void ReadXmlSchema ( string fileName ); public void ReadXmlSchema ( TextWriter writer); public void ReadXmlSchema ( XmlWriter writer ); public void InferXmlSchema ( Stream stream, string[] namespaces ); public void InferXmlSchema ( string fileName, string[] namespaces ); public void InferXmlSchema ( TextWriter writer, string[] namespaces ); public void InferXmlSchema ( XmlWriter writer, string[] namespaces ); } Überblick

397 Typed DataSets Typed DataSets provide typed data access
Tool xsd.exe generates classes from XML schema Classes define properties for typed access to rows, columns, and relations > xsd.exe personcontact.xsd /dataset Überblick

398 Example Typed DataSets
Data access in conventional DataSet DataSet ds = new DataSet("PersonContacts"); DataTable personTable = new DataTable("Person"); ... ds.Tables.Add(personTable); DataRow person = personTable.NewRow(); personTable.Rows.Add(person); person["Name"] = "Beer"; person.GetChildRows("PersonHasContacts")[0]["Name"] = "Beer"; Data access in typed DataSet PersonContacts typedDS = new PersonContacts(); PersonTable personTable = typedDS.Person; Person person = personTable.NewPersonRow(); personTable.AddPersonRow(person); person.Name = "Beer"; ... person.GetContactRows()[0].Name = "Beer"; Überblick

399 Access to DataSets using XML-DOM
XmlDataDocument allows to access DataSet over XML-DOM interface Synchronisation of changes in XmlDataDocument and DataSet XmlDataDocument xmlDoc = new XmlDataDocument(ds); ... DataTable table = ds.Tables["Person"]; table.Rows.Find(3)["Name"] = "Changed Name!"; Example: Create XmlDataDocument object for DataSet object Change data in DataSet XmlElement root = xmlDoc.DocumentElement; XmlNode person = root.SelectSingleNode(“/person[ID='3']"); Console.WriteLine("Access via XML: \n" + person.OuterXml); Access changed data from XmlDataDocument object Access via XML: <person id ="2"> <firstname>Dietrich</firstname> <name>Changed Name!</name> Überblick

400 ADO.NET Introduction Connection-oriented Access Connectionless Access
Database Access with DataAdapter Integration with XML ADO.NET 2.0 Summary Überblick

401 ADO.NET 2.0 Extended interfaces Tight coupling with MS SQL Server 2005
New features are (many only available for MS SQL Server 2005): bulk copy operation Multiple Active Result Sets (MARS) asynchronous execution of database operations batch processing of database updates paging through the result of a query Überblick

402 Bulk Copy Operation Inserting a large amount of data in one operation (only for MS SQL Server) Provided by class SqlBulkCopy Example 1. Define data source SqlConnection sourceCon = new SqlConnection(conString); sourceCon.Open(); SqlCommand sourceCmd = new SqlCommand("SELECT * FROM Customers",sourceCon); IDataReader sourceReader = sourceCmd.ExecuteReader(); 2. Define target SqlConnection targetCon = new SqlConnection(conString); targetCon.Open(); 3. Copy data from source to target in one operation SqlBulkCopy bulkCmd = new SqlBulkCopy (targetCon); bulkCmd.DestinationTableName = "Copy_Customers"; bulkCmd.WriteToServer(sourceReader); Überblick

403 Multiple Active Result Sets (MARS)
So far only one DataReader for one connection allowed ADO.NET 2.0 allows several DataReaders in parallel SqlConnection con = new SqlConnection(conStr); con.Open(); SqlCommand custCmd = new SqlCommand("SELECT CustomerId, CompanyName " + "FROM Customers ORDER BY CustomerId", con); SqlCommand ordCmd = new SqlCommand("SELECT CustomerId, OrderId, OrderDate " + "FROM Orders ORDER BY CustomerId, OrderDate", con); SqlDataReader custRdr = custCmd.ExecuteReader(); SqlDataReader ordRdr = ordCmd.ExecuteReader(); string custID = null; while (custRdr.Read()) { // use the first reader custID = custRdr.GetString(0); while (ordRdr.Read() && ordRdr.GetString(0) == custID ) { // use the second reader ... } Überblick

404 Asynchronous Operations
So far only synchronous execution of commands ADO.NET 2.0 supports asynchronous execution mode (similar to asynchronous IO operations) IAsyncResult BeginExecuteReader (AsyncCallback callback) IDataReader EndExecuteReader (AsyncResult result) IAsyncResult BeginExecuteNonQuery (AsyncCallback callback) int EndExecuteNonQuery (IAsyncResult result) IAsyncResult BeginExecuteXmlReader (AsyncCallback callback) IDataReader EndExecuteXmlReader (IAsyncResult result) Überblick

405 Example Asynchronous Operations
... public class Async { SqlCommand cmd; // command to be executed asynchronously public void CallCmdAsync() { SqlConnection con = new SqlConnection("Data Source=(local)\\NetSDK..."); cmd = new SqlCommand("MyLongRunningStoredProc", con); cmd.CommandType = CommandType.StoredProcedure; con.Open(); // execute the command asynchronously IAsyncResult r; r = cmd.BeginExecuteNonQuery(new AsyncCallback(AsyncCmdEnded), null); } // this callback method is executed when the SQL command is finished public void AsyncCmdEnded(IAsyncResult result) { cmd.EndExecuteNonQuery(result); // optionally do some work based on results Überblick

406 Batch Processing of Database Updates
So far rows are updated individually With ADO.NET 2.0 several rows can be updated in one batch (only available for MS SQL Server) UpdateBatchSize can be specified for DataAdapter void UpdateCategories(DataSet ds, SqlConnection con) { // create an adapter with select and update commands SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Categories", con); // the command builder creates the missing UPDATE, INSERT and DELETE commands SqlCommandBuilder cb = new SqlCommandBuilder(da); // set the batch size != 1 da.UpdateBatchSize = 50; // execute the update in batch mode da.Update(ds.Tables["Categories"] ); } Überblick

407 Web Services Introduction Web Services in .NET SOAP SOAP and .NET
Service Description with WSDL Discovery of Web Services: UDDI and DISCO Preview of Indigo Summary Überblick

408 Motivation Reasons for web services are similar to reasons for hierarchical component models Integration of heterogonous, distributed systems globally distributed different programming languages different APIs B2C and B2B applications Usage of globally distributed services Example: Travel Agent Service taken from: Web Services Architecture Usage Scenarios, W3C Working Group Note, 11 February 2004, Überblick

409 What are Web Services? Middleware for distributed applications
For remote procedure calls und data exchange Open standard based on XML Message based For loosely coupled software services Independent of programming languages and operating systems Utilizing existing Internet protocols and server architectures Überblick

410 Definition Web Service (by W3C)
Software application identified by URI interface description in XML (not object description) with interaction on the basis of XML encoded messages and message exchange on the basis of Internet protocols Überblick

411 Independence and Integration through ...
SOAP XML standard for message encoding independent of transport protocol independent of client and server implementations: Java, .NET, Python, … Web Services Description Language - WSDL (1.1) Interface description in XML communication on the basis of existing protocols and server architectures HTTP and Web server SMTP and mail server FTP and FTP server Standardization (W3C) SOAP 1.2, WSDL 1.1 (1.2 und 2.0) additional protocols based on SOAP and WSDL protocol bindings (HTTP) Überblick

412 Web-Services Szenario
Überblick

413 Web Services in Comparison
Java RMI .NET Remoting CORBA Web services Programming language Java .NET languages (C#, VB.NET, ..) independent Interface definition Java Interfaces .NET Interfaces CORBA IDL WSDL (XML-based) Data structures Java objects .NET objects IDL-specified objects XML data Transport protocol RMI-IIOP binary or OAP GIOP/IIOP HTTP, HTTPS, SMTP, FTP Packaging Java object serialization .NET object serialization ORB/CDR SOAP Infrastructure Java RMI infrastructure .NET remoting infrastructure ORBs Web, Mail, FTP server Überblick

414 Pros and Cons Pros independent of programming language, run time environment and operating system built on existing Internet infrastructure standardized promoted from important players (Microsoft, IBM, SAP, Sun) Cons performance (XML) not really object oriented Überblick

415 Web Service Infrastructure
Überblick

416 Web Service Architecture
Überblick

417 Web Service Architecture (2)
Überblick

418 Web Services Introduction Web Services in .NET SOAP SOAP and .NET
Service Description with WSDL Discovery of Web Services: UDDI and DISCO Preview of Indigo Summary Überblick

419 Web Services in .NET IIS and ASP.NET infrastructure support Web services .NET Framework provides several base classes attributes protocols for the realization of Web services Visual Studio.NET provides powerful tools for developing Web services implementation testing administration of IIS generation of proxy code (wsdl.exe) Überblick

420 .NET Namespaces System.Web.Services System.Web.Services.Configuration
for developing Web services (e.g.: WebService, WebMethod) System.Web.Services.Configuration for extending SOAP System.Web.Services.Description for creating and manipulating WSDL descriptions System.Web.Services.Discovery for using DISCO System.Web.Services.Protocols for implementation of communication protocols (e.g. SOAP-HTTP) System.Xml.Serialization for XML serialization Überblick

421 Implementation of Web Services
WebService Language="C#" Class="MyWebService" %> in asmx-file with @WebService directive asmx-File in a virtual directory in the IIS public class MyWebService : WebService { deriving from base class System.Web.Services.WebService [WebMethod(Description= “comment ")] […] public Returntype MyWebMethod( …) { Identification and settings by .NET attributes identification of Web service methods definition of format and encoding XML namespaces and element names to use etc. Überblick

422 stored in virtual directory
Example: TimeService stored in virtual directory time/TimeService.asmx TimeService.asmx WebService Language="C#" Class="TimeService" %> using System; using System.Web.Services; public class TimeService : WebService { [WebMethod(Description="Returns the current time")] public string GetTime(bool shortForm) { if (shortform) return DateTime.Now.ToShortTimeString(); else return DateTime.Now.ToLongTimeString(); } WebService directive deriving from WebService Attribute [WebMethod] identifies Web service method Überblick

423 WebService Description in IE
Überblick

424 Example: Simple .NET Client
> wsdl.exe /namespace:TimeClient /out:TimeServiceProxy.cs wsdl.exe generates proxy for client (TimeClient.TimeService) using System; using TimeClient; //Namespace of generated proxies public class NetClient { public static void Main(string[] args) { TimeService service = new TimeService(); Console.WriteLine(“Time at the server is: "); string time = service.GetTime(true); Console.WriteLine(time); } Client program creates TimeService object and calls GetTime Überblick

425 Example: Simple Java Client
Using GLUE tool + Java libraries: wsdl2Java create Java interface (ITimeServiceSoap) and proxy (TimeServiceHelper) import Kapitel7.GLUEProxy.*; // import generated GLUE proxy classes /** Simple XML Web service client in Java using GLUE */ public class JavaClientGLUE { public static void main(String[] args) { try { // Calling service using class and interface generated by wsdl2java ITimeServiceSoap service = TimeServiceHelper.bind(); String time = service.GetTime(true); System.out.println(“The time on the server is: \n" + time); } catch (Exception ex) { ex.printStackTrace(); } } Überblick

426 Web Services Introduction Web Services in .NET SOAP SOAP and .NET
Service Description with WSDL Discovery of Web Services: UDDI and DISCO Preview of Indigo Summary Überblick

427 SOAP Simple message protocol in XML Independent of transport protocol
for packaging arbitrary application data single messages only (“one-way“) asynchronous Independent of transport protocol SOAP does not define: distributed object model communication protocol distributed garbage collection distributed events (distributed callbacks) Überblick

428 Application of SOAP Client Server SOAP is extendable
method call protocol (RPC) security authentication etc. Protocol realisation by combination of messages (message exchange patterns) one-way, request-response, multicast, … Client Server e.g.: request-response for RPC by 2 messages 1: GetTime_Request 2: GetTime_Response Überblick

429 SOAP Messages SOAP messages comparable to letters with
envelope (<Envelope>) as container letter head (<Header>) with meta information (Message Headers) letter (<Body>) with arbitrary XML data fault descriptions Überblick

430 XML Structure (simplified, SOAP 1.2)
<?xml version="1.0" ?> <soap:Envelope xmlns:soap="..."> <soap:Header> <!-- (optional and extendable)   -->   <m:my xmlns:m="anURI" soap:mustUnderstand=“true" soap:role=“uri2" />   ...   </soap:Header> <soap:Body>  data (depends on encoding and format) <soap:Fault>  <soap:Code>...who is responsible?... </Code>   <soap:Reason>...textual description...</soap:Reason> <soap:Detail>...more error details...</soap:Detail> </soap:Fault>  </soap:Body>  </soap:Envelope> Überblick

431 Data in <Body> Part
Message format: document structure defined by XML schema rpc structure defined by SOAP for RPC Data encoding: literal encoding defined by XML schema encoded encoding defined by SOAP encoding rules Usual combinations: document/literal standard in .NET rpc/encoded often used by Java servers Überblick

432 HTTP Binding HTTP-GET, HTTP-POST
call encoded in HTTP (URL encoded) response encoded in XML Restricted to simple calls (no headers, no structured data) SOAP over HTTP-POST data part of POST request contains SOAP encoded call response SOAP encoded  No restrictions Überblick

433 Example: HTTP-POST Call of GetTime(bool shortForm) of Web service Call : HTTP/ OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <string xmlns=" HTTP response: Überblick

434 Example: SOAP over HTTP (1)
POST /time/TimeService.asmx HTTP/1.1 Content-type: text/xml; charset=utf-8 SOAPAction: Content-length: 198 User-Agent: Java1.4.0 Host: localhost Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap=" <soap:Body> <GetTime xmlns=" <shortForm> true </shortForm> < /GetTime> </soap:Body> </soap:Envelope> SOAP over HTTP-POST: HTTP header SOAPAction identifies SOAP request Web method Parameter Überblick

435 Example: SOAP over HTTP (2)
SOAP encoded response: HTTP/ OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap= xmlns:xsi= xmlns:xsd=" <soap:Body> <GetTimeResponse xmlns=" <GetTimeResult>string</GetTimeResult> </GetTimeResponse> </soap:Body> </soap:Envelope> Return value Überblick

436 Web Services Introduction Web Services in .NET SOAP SOAP and .NET
Service Description with WSDL Discovery of Web Services: UDDI and DISCO Preview of Indigo Summary Überblick

437 SOAP and .NET Uses .NET attributes extensively
.NET provides support for defining message format and encoding encoding of .NET data types development of message headers life cycle management Uses .NET attributes extensively Überblick

438 Message Format and Encoding (1)
[SoapRpcMethod( Use=SoapBindingUse.Encoded Action=" // SOAP action RequestNamespace=" RequestElementName="AddAddressRpcRequest", // SOAP element name ResponseNamespace=" ResponseElementName="AddAddressRpcResponse")] // SOAP element name [WebMethod(Description="Adds an address DataSet for the specified user")] public void AddAddressRpc(long userID, Address address) { ... } Attributes SoapRpcService and SoapRpcMethod for rpc format with parameters Use: encoding (SoapBindingUse.Literal or SoapBindingUse.Encoded) Action: URI for SOAPAction-HTTP header RequestNamespace and RequestElementName: namespace and name of SOAP element for request ResponseNamespace and ResponseElementName: namespace and name of SOAP element for response Überblick

439 Message Format and Encoding (2)
[SoapDocumentMethod(Use=SoapBindingUse.Literal, Action=" // SOAPAction RequestNamespace=" RequestElementName="AddAddressDocLitRequest", // SOAP element name ResponseNamespace=" ResponseElementName="AddAddressDocLitResponse")] // SOAP element name [WebMethod(Description="Adds an address DataSet for the specified user")] public void AddAddressDocLit(long userID, Address address) { ... } [SoapDocumentService(Use=SoapBindingUse.Encoded)] public class TimeService : WebService { ... } Attributes SoapDocumentService and SoapDocumentMethod for document format Überblick

440 SOAP Encoding of .NET Data Types
Serializing of .NET data types on the basis of SOAP encoding rules adjusted by attributes (namespace System.Web.Serialization) SoapAttributeAttribute Serializing field as XML attribute SoapElementAttribute Serializing field as XML element SoapIgnoreAttribute No serialization of field SoapIncludeAttribute Including a type SoapEnumAttribute Adapting name of enumeration Überblick

441 Example: Encoding of a Type (1)
Web method GetTimeDesc uses type TimeDesc for return value [WebMethod(Description="Returns the time description of the server")] public TimeDesc GetTimeDesc() { TimeDesc td = new TimeDesc(); // ... return td; } public struct TimeDesc { [SoapAttribute] public string TimeLong; [SoapAttribute] public string TimeShort; [SoapAttribute (AttributeName = "ZoneID")] public int TimeZone; } Encoding of TimeDesc adjusted by attribute [SoapAttribute]  fields encoded as XML attributes Überblick

442 Example: Encoding of a Type (2)
SOAP encoded response ... <soap:Envelope xmlns:soap=" ... <soap:Body soap:encodingStyle=" <types:GetTimeDescResponse> <GetTimeDescResult href="#id1" /> </types:GetTimeDescResponse> <types:TimeDesc id="id1" xsi:type="types:TimeDesc" types:TimeLong="10:00:25" types:TimeShort="10:00" types:ZoneID="1" /> </soap:Body> </soap:Envelope> Überblick

443 Including Types SoapIncludeAttribute allows inclusion of types  important for specializations Example: PersonService public class PersonService : WebService { [WebMethod]… public Person[ ] GetAll() {…} } Web method with return value of type Person[] Person Customer Employee Person has 2 specializations Customer and Employee  Customer and Employee have to be included explicitly into Web service description! Überblick

444 Example: PersonService (1)
Classes Person, Customer and Employee public abstract class Person { …} public class Customer : Person { …} public class Employee : Person {…} WebService Language="C#" Class="PersonService" %> using System; … using System.Xml.Serialization; public class PersonService : WebService { [WebMethod] [SoapRpcMethod] [SoapInclude(typeof(Customer)), SoapInclude(typeof(Employee))] public Person[] GetAll() { Person[] data = new Person[2]; data[0] = new Customer("1“, "Max Customer", "EMP-33"); data[1] = new Employee("EMP-33", "Tom Employee"); return data; } PersonService defines web method GetAll with return type Person[] SoapInclude attribute includes Customer and Employee types Includes subtypes Überblick

445 Example: PersonService (2)
SOAP encoded response <soap:Envelope xmlns:soap=" ... > <soap:Body soap:encodingStyle=" <tns:GetAllResponse> <GetAllResult href="#id1" /> </tns:GetAllResponse> <soapenc:Array id="id1" soapenc:arrayType="types:Person[2]"> <Item href="#id2" /> <Item href="#id3" /> </soapenc:Array> <types:Customer id="id2" xsi:type="types:Customer"> <SSN xsi:type="xsd:string">1</SSN> <Name xsi:type="xsd:string">Max Customer</Name> <EmpSSN xsi:type="xsd:string">EMP-33</EmpSSN> </types:Customer> <types:Employee id="id3" xsi:type="types:Employee"> <SSN xsi:type="xsd:string">EMP-33</SSN> <Name xsi:type="xsd:string">Tom Employee</Name> </types:Employee> </soap:Body> </soap:Envelope> Überblick

446 SOAP Header Entries SOAP header entries are used for meta informations in messages Arbitrary header entries are possible, e.g. e.g. authentication of clients All header entries have attributes recipient of entry (Actor) if it must be handled by recipient (mustUnderstand) .NET supports header entries by: Class SoapHeader: Development of header entry classes Attribute SoapHeaderAttribute: Defining header entries for web methods Überblick

447 Classes SoapHeader and SoapHeaderAttribute
Recipient Header must be handled Header handled successfully In-, Out-, InOut direction of headers Field of Web service for the header entry public string Actor {get; set;} public SoapHeaderDirection Direction {get; set;} public bool MustUnderstand {get; set;} public string MemberName {get; set;} public bool DidUnderstand {get; set;} Überblick

448 "curUser" is a field for AuthHeader
Example: AuthHeader Identification of user in TimeService Login returns identification code (cookie) GetTime sends back identification code in header entry Header class AuthHeader defines public field cookie public class AuthHeader : SoapHeader { public string cookie; } [WebMethod(Description="Returns the current time")] [SoapHeader("curUser")] public string GetTime() { …. [WebService(Namespace=" public class HeaderTimeService : WebService { public AuthHeader curUser; "curUser" is a field for AuthHeader Überblick

449 :HeaderTimeServiceProxy
Example: AuthHeader Identification of user in TimeService Login returns identification code (cookie) GetTime sends back identification code in header entry :HeaderTimeService :HeaderTimeServiceProxy :Client cookie = Login(user, pw) <soap:Envelope>.. <Login> <…. </soap> Login(..) <soap:Envelope>..<cookie>afah2..</cookie> </soap> "afah2320u799a8d" entry = new AuthHeader(cookie) AuthHeaderValue = entry <soap:Envelope> <Headers> <AuthHeader> <cookie>afah2320u799a8d</cookie> </AuthHeader> </Headers> <GetTime> … </GetTime> </soap> GetTime() curUser= GetTime Validate Cookie(..) <soap:Envelope>..<GetTimeResponse>17:5s</… </soap> 17:52 Überblick

450 Example: AuthHeader (1)
Identification of user in TimeService Login returns identification code (cookie) GetTime sends back identification code in header entry Header class AuthHeader defines public field cookie public class AuthHeader : SoapHeader { public string cookie; } Web service class defines field curUser to store AuthHeader object [WebService(Namespace=" public class HeaderTimeService : WebService { public AuthHeader curUser; Login with user and password returns identification string [WebMethod (Description="Authenticates the user")] public string Login(string user, string pwd) { ... create cookie ... } bool ValidateCookie(string cookie) { ... validate cookie ... } Überblick

451 Example: AuthHeader (2)
GetTime requires header entry of type AuthHeader which will be stored in field curUser Validates user based on login data [WebMethod(Description="Returns the current time")] [SoapHeader("curUser")] public string GetTime() { if (curUser != null && ValidateCookie(curUser.cookie)) return System.DateTime.Now.ToLongTimeString(); else throw new SoapHeaderException("Access denied!", SoapException.ClientFaultCode); } Überblick

452 Example: AuthHeader (3)
Client creates service proxy and AutHeader object HeaderTimeService proxy = new HeaderTimeService(); AuthHeader entry = new AuthHeader(); receives cookie from call to Login entry.cookie = proxy.Login(user, pwd); sets the AuthorHeader in proxy calls GetTime with AuthHeader header entry proxy.AuthHeaderValue = entry; Console.WriteLine(proxy.GetTime()); <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap=" ... > <soap:Header> <AuthHeader xmlns=" <cookie>aewt12348cvNNgrt55</cookie> </AuthHeader> </soap:Header> <soap:Body> <GetTime xmlns=" /> </soap:Body> </soap:Envelope> Überblick

453 Life Cycle Web service objects are stateless
are created for each call Data can be stored in properties of Application state object or Sesssion state object public HttpApplicationState Application {get;} defined in base class WebService ! public HttpApplicationState Session {get;} public sealed class HttpSessionState : ICollection, IEnumerable { public object this[ string name ] {get; set;} public object this[ int index ] {get; set;} } Überblick

454 Example: StateDemo (1) WebService Language="C#" Class="StateDemo" %> using System.Web.Services; [WebService(Namespace=" public class StateDemo : WebService { Web service StateDemo demonstrates storage of data IncApplication increases property "Hit" of Application state object [WebMethod()] public int IncApplication() { int hit = (Application["Hit"] == null) ? 0 : (int) Application["Hit"]; hit++; Application["Hit"] = hit; return hit; } Überblick

455 Example: StateDemo (2) Parameter EnableSession enables usage of Session object IncSeesion increases property "Hit" of Session state object [WebMethod(EnableSession=true)] public int IncSession() { int hit = (Session["Hit"] == null) ? 0 : (int) Session["Hit"]; hit++; Session["Hit"] = hit; return hit; } Überblick

456 Web Services Introduction Web Services in .NET SOAP SOAP and .NET
Service Description with WSDL Discovery of Web Services: UDDI and DISCO Preview of Indigo Summary Überblick

457 Web Service Description Language (WSDL)
WSDL is an XML-based IDL for Web services a WSD describes: used data types structure of messages operations (methods) protocols to call operations addresses of Web service current version in .NET: WSDL 1.1 ( Working Draft: WSDL 2.0 (10/4/2004) Überblick

458 Structure of WSDL 1.1 abstract part concrete part <definitions>
<types> </types> <message> <part> </part> </message> <portType> <operation> <input> <output> </operation> </portType> <binding> </binding> <service> <port> </service> </definitions> WSDL description of a Web services types defined in <xsd:schema> simple messages parts of messages interface specification operations of an interface input message output message binding of interface to protocols and encoding description of the binding for each operation service description URI and binding to port concrete part Überblick

459 Example: WSDL for TimeService (1)
WSDL description created by web container (IIS) <?xml version="1.0" encoding="utf-8"?> <definitions xmlns:soap= xmlns:tns=" xmlns:s=" xmlns:http=" xmlns:mime=" xmlns:soapenc=" targetNamespace=" xmlns=" <types /> <message name="GetTimeSoapIn" /> <message name="GetTimeSoapOut"> <part name="GetTimeResult" type="s:string" /> </message> <portType name="TimeServiceSoap"> <operation name="GetTime"> <input message="tns:GetTimeSoapIn" /> <output message="tns:GetTimeSoapOut" /> </operation> </portType> abstract part Überblick

460 Example: WSDL for TimeService (2)
<binding name="TimeServiceSoap" type="tns:TimeServiceSoap"> <soap:binding transport=" style="rpc" /> <operation name="GetTime"> <soap:operation soapAction=" style="rpc" /> <input> <soap:body use="encoded" namespace=" encodingStyle=" /> </input> <output> </output> </operation> </binding> <service name="TimeService"> <documentation>Simple Web service for querying the time</documentation> <port name="TimeServiceSoap" binding="tns:TimeServiceSoap"> <soap:address location=" /> </port> </service> </definitions> concrete part Überblick

461 Web Services Introduction Web Services in .NET SOAP SOAP and .NET
Service Description with WSDL Discovery of Web Services: UDDI and DISCO Preview of Indigo Summary Überblick

462 Universal, Description, Discovery and Integration (UDDI)
Standardized protocol for searching for and using Web services Provides Web services interface Directory (UDDI) 1.) register 2.) search Client Web Service A Web Service B 3.) connect 4.) call Überblick

463 DISCO Microsoft’s technique for dynamic usage of Web services
DISCO file contains XML document with URIs pointing to Web services can be the result of a UDDI inquiry .NET support in namespace System.Web.Services.Discovery Überblick

464 DISCO Descriptions Creation of DISCO descriptions:
by command tool disco.exe by IIS > disco.exe /out:WebProject1 WebProject1/TimeService.asmx <?xml version="1.0" encoding="utf-8" ?> <discovery xmlns:xsd=" xmlns:xsi=" xmlns=" <contractRef ref=" docRef=" xmlns=" /> <soap address=" xmlns:q1=" binding="q1:TimeServiceSoap" xmlns=" /> </discovery> Access WSDL Call Überblick

465 Example: TimeService Discovery (1)
2 variants of TimeService TimeService1 TimeService2 WebService Language="C#" Class="TimeService1" %> using System.Web.Services; [WebService(Namespace=" Name="TimeService")] public class TimeService1 : WebService { [WebMethod(Description="Returns the current server time")] public string GetTime() { return System.DateTime.Now.ToLongTimeString(); } } WebService Language="C#" Class="TimeService2" %> using System.Web.Services; [WebService(Namespace=" Name="TimeService")] public class TimeService2 : WebService { [WebMethod] public string GetTime() { return "I don’t know the time!"; } } Überblick

466 Example: TimeService Discovery (2)
Disco client with discovery of DISCO file using System; using System.Web.Services.Discovery; using System.Collections; public class DiscoSample { public static void Main(string[] args) { loading the DISCO files DiscoveryClientProtocol discoClient = new DiscoveryClientProtocol(); foreach (string uri in args) { discoClient.Discover(uri); } URI of Disco-documents from commmand line iterating over all DISCO descriptions discoClient.ResolveAll(); TimeService proxy = new TimeService(); foreach (object obj in discoClient.Documents.Values) { DiscoveryDocument dDoc = obj as DiscoveryDocument; Überblick

467 Example: TimeService Discovery (3)
iterating over all <contactRef>-elements and retrieve URLs ContractReference contr = null; IEnumerator it = dDoc.References.GetEnumerator(); while (contr == null && it.MoveNext()) contr = it.Current as ContractReference; based on the URL, connect to Web service and call Web method if (contr != null) { proxy.Url = contr.DocRef; Print("Connecting proxy to " + proxy.Url); proxy.Discover(); Print("Result of GetTime: " + proxy.GetTime()); } static void Print(string msg) { System.Console.WriteLine(msg); } Result of GetTime: 17:52 Result of GetTime: I don’t know the time! Überblick

468 Web Services Introduction Web Services in .NET SOAP SOAP and .NET
Service Description with WSDL Discovery of Web Services: UDDI and DISCO Preview of Indigo Summary Überblick

469 Indigo Indigo unites in one uniform programming model Indigo provides
.NET remoting Web services .NET Enterprise Services in one uniform programming model Indigo provides transactions reliable communication secure communication and authentication independence of transport protocols host independence message-based server activation Announced with Windows Vista Überblick

470 Indigo Architecture Überblick

471 Indigo Web Service Example (1)
Implementation of Web service TimeService using System; using System.MessageBus.Services; [DatagramPortType(Name="TimeService", Namespace=" public class TimeService { [ServiceMethod] public DateTime GetTime() { DateTime now = DateTime.Now; Console.WriteLine ("Time request at {0}", now); // output to monitor server return now; } Compiling and creation of assembly csc /target:library /reference:System.MessageBus.dll TimeService.cs Creating the WSDL description wsdlgen TimeService.dll Überblick

472 Indigo Web Service Example (2)
Implementation of the server application using System; using System.MessageBus.Services; using System; using System.MessageBus; class Server { static void Main () { ServiceEnvironment se = null; try { se = ServiceEnvironment.Load(); se.Open(); Console.WriteLine("Press enter to stop the service ..."); Console.ReadLine(); } finally { if (se != null) se.Close(); } } Überblick

473 Indigo Web Service Example (3)
Configuration of the server in file Server.exe.config <configuration> <system.messagebus> <serviceEnvironments> <serviceEnvironment name="main"> <port> <identityRole> soap.tcp://localhost:12345/TimeService/ </identityRole> </port> <remove name="securityManager"/> <!-- Security disabled!!! --> <policyManager> <areUntrustedPolicyAttachmentsAccepted> true </areUntrustedPolicyAttachmentsAccepted> <isPolicyReturned> true </isPolicyReturned> </policyManager> <serviceManager> <activatableServices> <add type="TimeService, TimeService" /> </activatableServices> </serviceManager> </serviceEnvironment> </serviceEnvironments> </system.messagebus> </configuration> Überblick

474 Indigo Web Service Example (4)
Compilation of the server application csc /reference:System.MessageBus.dll Server.cs Creation of the proxy for the client wsdlgen dotnet_jku_at.WS.wsdl dotnet_jku_at.WS.xsd Compilation of the proxy code csc /target:library /reference:System.MessageBus.dll dotnet_jku_at.WS.cs Überblick

475 Indigo Web Service Example (5)
Implementation of the client application using System; using System.MessageBus.Services; public class Client { public static void Main () { ServiceEnvironment se = null; try { se = ServiceEnvironment.Load(); ServiceManager sm = se[typeof(ServiceManager)] as ServiceManager; if (sm == null) throw new Exception("ServiceManager is not available."); se.Open(); Uri uri = new Uri("soap.tcp://localhost:12345/TimeService/"); // get a channel to the Web service from the default service manager ITimeServiceChannel channel = (ITimeServiceChannel) sm.CreateChannel(typeof(ITimeServiceChannel), uri); Console.WriteLine(channel.GetTime());// invoke Web service method } catch (Exception e) { Console.WriteLine(e); } finally { if (se != null) se.Close(); } } Configuration of the client (analogous to the server) and compilation csc /reference:System.MessageBus.dll,dotnet_jku_at.WS.dll Client.cs Überblick

476 Indigo Web Service Example (6)
Configuration of the client in file Client.exe.config <configuration> <system.messagebus> <serviceEnvironments> <serviceEnvironment name="main"> <port> <identityRole> soap.tcp://localhost:12346/TimeClient/ </identityRole> </port> <remove name="securityManager"/> <!-- Security disabled!!! --> <policyManager> <areUntrustedPolicyAttachmentsAccepted> true </areUntrustedPolicyAttachmentsAccepted> <isPolicyReturned> true </isPolicyReturned> </policyManager> </serviceEnvironment> </serviceEnvironments> </system.messagebus> </configuration> Überblick

477 Indigo Web Service Example (6)
Starting the server and the client //----- Server > Host.exe Press enter to stop the service ... Time request at 1/29/2004 3:35:51 PM > //----- Client > Client.exe Time request at 1/29/2004 3:35:51 PM > Überblick

478 Indigo RemoteObject Example
Implementation of the RemoteObject class using System; using System.Globalization; public class TimeZoneObject : MarshalByRefObject { private Guid myID = Guid.NewGuid (); private TimeSpan myOffset; public TimeZoneObject (string tz) { myOffset = ConvertZoneToUtcOffset (tz); Console.WriteLine("Creating object {0} for zone {1}", myID, tz); } public string GetCurrentTimeAndDate (CultureInfo ci) { if (ci == null) ci = new CultureInfo (""); Console.WriteLine("{0} returning current time/date for culture {1}", myID, ci.ToString()); return (DateTime.UtcNow + myOffset).ToString ("F", ci); public string GetUtcTimeAndDate (CultureInfo ci) { return DateTime.UtcNow.ToString ("F", ci); private TimeSpan ConvertZoneToUtcOffset (string tz) { string upperTZ = tz.ToUpper(); switch (upperTZ) { case "ADT": // Atlantic Daylight -3 hours return new TimeSpan (-3, 0, 0); case "AST": // Atlantic Standard case "EDT": // Eastern Daylight -4 hours return new TimeSpan (-4, 0, 0); default: throw new Exception ("Unrecognized time zone"); Überblick

479 Indigo RemoteObject Example
Hosting the RemoteObject class using System; using System.MessageBus; using System.MessageBus.Remoting; class Host { static void Main () { ServiceEnvironment se = null; try { se = ServiceEnvironment.Load (); RemotingManager rm = se[typeof(RemotingManager)] as RemotingManager; if (rm == null) throw new Exception("No RemotingManager in ServiceEnvironment."); se.Open (); TimeZoneObject tzoPST = new TimeZoneObject ("PST"); TimeZoneObject tzoHAW = new TimeZoneObject ("HAW"); PublishedServerObject psoPST = new PublishedServerObject (tzoPST, new Uri("urn:PST")); rm.PublishedServerObjects.Add (psoPST); PublishedServerObject psoHAW = new PublishedServerObject (tzoHAW, new Uri("urn:HAW")); rm.PublishedServerObjects.Add (psoHAW); Console.WriteLine("Listening for requests. Press Enter to exit..."); Console.ReadLine(); // Cancel the publication of the objects. rm.PublishedServerObjects.Remove(psoPST); rm.PublishedServerObjects.Remove(psoHAW); } finally { if (se != null) se.Close(); Überblick

480 Indigo RemoteObject Example
Configuration of the host in file Host.exe.config <configuration> <system.messagebus> <serviceEnvironments> <serviceEnvironment name="main"> <port> <identityRole> soap.tcp://localhost:12345/TimeZoneObjects/ </identityRole> </port> <remove name="securityManager"/> <!-- Security disabled!!! --> <policyManager> <areUntrustedPolicyAttachmentsAccepted> true </areUntrustedPolicyAttachmentsAccepted> <isPolicyReturned> true </isPolicyReturned> </policyManager> <remotingManager> </remotingManager> </serviceEnvironment> </serviceEnvironments> </system.messagebus> </configuration> Überblick

481 Indigo RemoteObject Example
Client of the RemoteObject class using System; using System.Globalization; using System.MessageBus; using System.MessageBus.Remoting; class Client { static void Main (string[] args) { string zone; ServiceEnvironment se = null; try { se = ServiceEnvironment.Load (); RemotingManager rm = se[typeof(RemotingManager)] as RemotingManager; if (rm == null) throw new Exception("No RemotingManager in ServiceEnvironment."); se.Open(); Uri serverPortUri = new Uri("soap.tcp://localhost:12345/TimeZoneObjects"); string urn = "urn:" + zone; TimeZoneObject tzo = rm.GetObject (serverPortUri, new Uri(urn)) as TimeZoneObject; if (tzo != null) { Console.WriteLine ("It is currently {0} in the {1} time zone.", tzo.GetCurrentTimeAndDate (ci), zone); } else { Console.WriteLine ("Could not connect to the remote object."); finally { if (se != null) se.Close(); Überblick

482 Indigo RemoteObject Example
RemoteObject host for client creatable objects using System; using System.MessageBus; using System.MessageBus.Remoting; class Host { static void Main() { ServiceEnvironment se = null; try { se = ServiceEnvironment.Load (); se.Open (); Console.WriteLine ("Listening for requests. Press Enter to exit..."); Console.ReadLine (); } finally { if (se != null) se.Close (); Überblick

483 Indigo RemoteObject Example
Configuration of the host in file Host.exe.config <configuration> <system.messagebus> <serviceEnvironments> <serviceEnvironment name="main"> <port> <identityRole> soap.tcp://localhost:12345/TimeZoneObjects/ </identityRole> </port> <remove name="securityManager"/> <!-- Security disabled!!! --> <policyManager> <areUntrustedPolicyAttachmentsAccepted> true </areUntrustedPolicyAttachmentsAccepted> <isPolicyReturned> true </isPolicyReturned> </policyManager> <remotingManager> <publishedServerTypes> <add type="TimeZoneObject, TimeZoneObject"/> </publishedServerTypes> </remotingManager> </serviceEnvironment> </serviceEnvironments> </system.messagebus> </configuration> Überblick

484 Secured Indigo Web Service
Implementation of Web service TimeService using System; using System.MessageBus.Services; [DatagramPortType(Name="TimeService", Namespace=" public class TimeService { [ServiceSecurity(Name="GetTimeScope", Role="StandardUserRole")] [ServiceMethod] public DateTime GetTime() { DateTime now = DateTime.Now; Console.WriteLine ("Time request at {0}", now); // output to monitor server return now; } Überblick

485 Secured Indigo Web Service Example
Configuration of the server in file Server.exe.config <configuration> <system.messagebus> <serviceEnvironments> <serviceEnvironment name="main"> <port> <identityRole> soap.tcp://localhost:12345/TimeService/ </identityRole> </port> <securityManager> <applicationSecurity> <binding scope="GetTimeScope" profile="userNamePassword" /> </applicationSecurity> </securityManager> <policyManager> <areUntrustedPolicyAttachmentsAccepted> true </areUntrustedPolicyAttachmentsAccepted> <isPolicyReturned> true </isPolicyReturned> </policyManager> <serviceManager> <activatableServices> <add type="TimeService, TimeService" /> </activatableServices> </serviceManager> </serviceEnvironment> </serviceEnvironments> </system.messagebus> </configuration> Überblick

486 Secured Indigo Web Service Example
Security of the server in file Server.exe.security <securityData> <credentials> <username id="mainUsers" nonceLength="24"> <memoryPasswordResolver> <add user="Brent" password="password1" /> <add user="Lisa" password="password2" /> </memoryPasswordResolver> </username> </credentials> <authorizationData> <memoryMapping id="mainAuthorizationData"> <globalEntries> <userNameRoleAssignment user="Brent" roles = "StandardUserRole"/> <userNameRoleAssignment user="Lisa" roles = "StandardUserRole"/> </globalEntries> </memoryMapping> </authorizationData> </securityData> Überblick

487 Secured Indigo Web Service Example
Security of the client in file Client.exe.security <securityData> <tokens> <tokenCache id="mainTokenCache"> <userNameToken user="Brent" password="password"/> <userNameToken user="Lisa" password="wordpass"/> </tokenCache> </tokens> </securityData> Überblick

488 ASP.NET Simple Dynamic Web Pages Web Forms Event Handling Web Controls
Validators User Controls Custom Controls State Management Configuration of ASP.NET Working with Visual Studio .NET Überblick

489 Static Web Pages Pure HTML My.html Server Browser (IIS) <html>
<head> <title>Simple HTML page</title> </head> <body> <h1>Welcome</h1> You are visitor number 1! </body> </html> My.html Request("My.html") Server (IIS) Browser Response(My.html) My.html Überblick

490 Dynamic ASPX Pages Computed values can be inserted into HTML code
Counter.aspx Page Language="C#" %> Import Namespace="System.IO" %> <html> <head> <title>Page counter</title> </head> <body> <h1>Welcome</h1> You are visitor number <% FileStream s = new FileStream("c:\\Data\\Counter.dat", FileMode.OpenOrCreate); int n; try { BinaryReader r = new BinaryReader(s); n = r.ReadInt32(); } catch { n = 0; } // if the file is empty n++; s.Seek(0, SeekOrigin.Begin); BinaryWriter w = new BinaryWriter(s); w.Write(n); s.Close(); Response.Write(n); %> ! </body> </html> Counter.aspx must be in a virtual directory. Überblick

491 What Happens Behind the Scene?
client (browser) response (*.html) *.html ASP.NET request ("Counter.aspx") Counter.aspx "Counter.aspx" page class preprocessor, compiler server (IIS) loader page object .NET framework Überblick

492 HTML Code Returned by the Server
Counter.aspx Returned HTML code Page Language="C#" %> Import Namespace="System.IO" %> <html> <head><title>Page Counter</title></head> <body> <h1>Welcome</h1> You are visitor number <% FileStream s = new FileStream(...); ... Response.Write(n); %> ! </body> </html> <html> <head><title>Page counter</title></head> <body> <h1>Welcome</h1> You are visitor number 6 ! </body> </html> does not contain any script code any browser can display this HTML Überblick

493 Code in Script Tags Counter.aspx short form for
Page Language="C#" %> Import Namespace="System.IO" %> <html> <head> <title>Page counter</title> <script Language="C#" Runat="Server"> int CounterValue() { FileStream s = new FileStream("c:\\Data\\Counter.dat", FileMode.OpenOrCreate); ... n = r.ReadInt32(); n++; return n; } </script> </head> <body> <h1>Welcome</h1> You are visitor number <%=CounterValue()%> ! </body> </html> Counter.aspx short form for Response.Write(CounterValue()); Überblick

494 Code Behind Counter.aspx CounterPage.cs
Page Language="C#" Inherits="CounterPage" Src="CounterPage.cs" %> <html> <head> <title>Page counter</title> </head> <body> <h1>Welcome</h1> You are visitor number <%=CounterValue()%> ! </body> </html> using System.IO; public class CounterPage : System.Web.UI.Page { public int CounterValue() { FileStream s = new FileStream("c:\\Data\\Counter.dat", FileMode.OpenOrCreate); ... n = r.ReadInt32(); n++; return n; } CounterPage.cs Überblick

495 Generated Page Class System.Web.UI.Page aspx page Counter_aspx ...
Page Language="C#"%> <html> <body> ... <%= ... %>... </body> </html> Counter_aspx ... Überblick

496 Generated Page Class System.Web.UI.Page Code behind CounterPage
CounterPage.cs public class CounterPage : System.Web.UI.Page { public int CounterValue() { ... } CounterPage CounterValue() aspx page Counter.aspx Page ... Inherits="CounterPage"%> <html> <body> ... <%=CounterValue()%>... </body> </html> Counter_aspx ... Überblick

497 Generated Class Counter_aspx
namespace ASP { using System.IO; ... public class Counter_aspx : CounterPage { private static bool __initialized = false; private static ArrayList __fileDependencies; public Counter_aspx() { ArrayList dependencies; if ((__initialized == false)) { ... } } public override string TemplateSourceDirectory { get { return "/Samples"; } private void __BuildControlTree(Control __ctrl) { __ctrl.SetRenderMethodDelegate(new RenderMethod(this.__Render__control1)); private void __Render__control1(HtmlTextWriter __output, Control parameterContainer) { __output.Write("\r\n<html>\r\n\t<head> <title>Page counter</title> </head>\r\n\t<body>\r\n\t\t" + "<h1>Welcome</h1>\r\n\t\tYou are visitor number "); __output.Write(CounterValue()); __output.Write(" !\r\n\t</body>\r\n</html>\r\n"); protected override void FrameworkInitialize() { __BuildControlTree(this); this.FileDependencies = __fileDependencies; this.EnableViewStateMac = true; this.Request.ValidateInput(); Überblick

498 ASP.NET Simple Dynamic Web Pages Web Forms Event Handling Web Controls
Validators User Controls Custom Controls State Management Configuration of ASP.NET Working with Visual Studio .NET Überblick

499 HTML Forms (With CGI Scripts)
... <body> <form action=" method="post"> <b>Balance:</b> <input type="text" name="total" readonly value="0"> Euro<br> <input type="text" name="amount"> <input type="submit" name="ok" value="Pay"> </form> </body> CGI script myprog - reads total and amount - sends back a new HTML text in which total and amount have new values Problems - CGI programming is tedious - restricted to HTML elements - must manage the state of text fields manually when the page is sent back Überblick

500 Web Forms in ASP.NET Adder.aspx
Page Language="C#" Inherits="AdderPage" Src="Adder.aspx.cs"%> <html> <head><title>Account</title></head> <body> <form method="post" Runat="server"> <b>Balance:</b> <asp:Label ID="total" Text="0" Runat="server"/> Euro<br><br> <asp:TextBox ID="amount" Runat="server"/> <asp:Button ID="ok" Text="Enter" Runat="server" /> </form> </body> </html> Überblick

501 Web Forms in ASP.NET Adder.aspx Adder.aspx.cs
Page Language="C#" Inherits="AdderPage" Src="Adder.aspx.cs"%> <html> <head><title>Account</title></head> <body> <form method="post" Runat="server"> <b>Balance:</b> <asp:Label ID="total" Text="0" Runat="server"/> Euro<br><br> <asp:TextBox ID="amount" Runat="server"/> <asp:Button ID="ok" Text="Enter" OnClick="ButtonClick" Runat="server" /> </form> </body> </html> using System; using System.Web.UI; using System.Web.UI.WebControls; public class AdderPage : Page { protected Label total; protected TextBox amount; protected Button ok; public void ButtonClick (object sender, EventArgs e) { int totalVal = Convert.ToInt32(total.Text); int amountVal = Convert.ToInt32(amount.Text); total.Text = (totalVal + amountVal).ToString(); } Adder.aspx.cs Überblick

502 HTML Code Sent Back to the Browser
Counter.aspx HTML code that is sent back to the browser Page Language="C#" Inherits="AdderPage" Src="Adder.aspx.cs"%> <html> <head><title>Account</title></head> <body> <form method="post" Runat="server"> <b>Balance:</b> <asp:Label ID="total" Text="0" Runat="server"/> Euro<br><br> <asp:TextBox ID="amount" Runat="server"/> <asp:Button ID="ok" Text="Enter" OnClick="ButtonClick" Runat="server" /> </form> </body> </html> <html> <head> <title>Account</title> </head> <body> <form name="_ctl0" method="post" action="Adder.aspx" id="_ctl0"> <input type="hidden" name="__VIEWSTATE" value="dDwxNTg0NTEzNzMyO3Q8O2w8aTwxP" + "js+O2w8dDw7bDxpPDE+Oz47bDx0PHA8cDxs"+ "PFRleHQ7PjtsPDEwMDs+Pjs+Ozs+Oz4+Oz4+" + "Oz7uOgbDI3uKWY/X5D1Fw8zmjTZkwg==" /> <b>Balance:</b> <span id="total">100</span> Euro<br><br> <input type="text" name="amount" value="100" id="amount" /> <input type="submit" name="ok" value="Enter" id="ok" /> </form> </body> </html> Überblick

503 General Notation for Web Controls
<asp:ClassName PropertyName="value" ... Runat="server" /> Example <asp:Label ID="total" Text="Hello" ForeColor="Red" Runat="server" /> public class Label: WebControl { public virtual string ID { get {...} set {...} } public virtual string Text { get {...} set {...} } public virtual Color ForeColor { get {...} set {...} } ... } All web control classes are in the namespace System.Web.UI Alternative Notation <asp:Label ID="total" ForeColor="Red" Runat="server" > Hello </asp:Label> Überblick

504 Advantages of Web Forms
The page is an object one can access all its properties and methods: page.IsPostBack, page.User, page.FindControl(), ... All GUI elements are objects one can access all their properties and methods: amount.Text, amount.Font, amount.Width, ... One can implement custom GUI elements Web pages can access the whole .NET library databases, XML, RMI, ... The state of all GUI elements is retained amount.Text does not need to be set before the page is sent back Überblick

505 Web Controls (selection)
Label TextBox Button RadioButton CheckBox DropDownList ListBox Calendar DataGrid ... User Controls Custom Controls abc Überblick

506 Web Control Hierarchy ... ... ... Control WebControl TemplateControl
ID Page Visible ... WebControl TemplateControl Font Width Height ... ... Button TextBox Label Page UserControl Text Text Rows Columns Text Request Response IsPostBack Überblick

507 ASP.NET Simple Dynamic Web Pages Web Forms Event Handling Web Controls
Validators User Controls Custom Controls State Management Configuration of ASP.NET Working with Visual Studio .NET Überblick

508 Event-based Processing
mouse click click event event handler void DoClick (object sender, EventArgs e) { ... } <asp:Button Text="..." OnClick="DoClick" Runat="sever" /> Client Server Überblick

509 Kinds of Events Control Event When does the event occur? all Init Load
PreRender Unload when the control is created after the data that were sent by the browser have been loaded into the control before HTML code for this control is generated before the control is removed from memory Button Click when the button was clicked TextBox TextChanged when the contents of the TextBox changed CheckBox CheckedChanged when the state of the CheckBox changed ListBox SelectedIndexChanged when a new item from the list has been selected Überblick

510 Round Trip of a Web Page Client Server round trip event Page
+ page state Label TextBox Click Button 1. Creation create page object and its controls Client Server Überblick

511 Round Trip of a Web Page Client Server round trip event Init Page
+ page state Label Init TextBox Init Click Button Init 2. Initialisation - raise Init events Client Server Überblick

512 Round Trip of a Web Page Client Server round trip event Load Page
+ page state Label Load TextBox Load Click Button Load 3. Loading - load controls with the values that the user has entered (page state) - raise Load events Client Server Überblick

513 Round Trip of a Web Page Client Server Page Label TextBox Button
4. Action handle event(s) (Click, TextChanged, ...) Client Server Überblick

514 Round Trip of a Web Page Client Server PreRender Page Label PreRender
TextBox PreRender HTML <html> ... <input type="text" ...> <input type="button" ...> </html> Button PreRender + page state 5. Rendering - raise PreRender events - call Render methods of all controls, which render the controls to HTML Client Server Überblick

515 Round Trip of a Web Page Client Server Unload Page Label Unload
TextBox Unload <html> ... <input type="text" ...> <input type="button" ...> </html> Button Unload 6. Unloading - raise Unload events for cleanup actions Client Server Überblick

516 Which Events Cause a Round Trip?
Round trip events (cause an immediate round trip) Click <asp:Button Text="click me" Runat="server" OnClick="DoClick" /> Delayed events (are handled at the next round trip) TextChanged <asp:TextBox Runat="server" OnTextChanged="DoTextChanged" /> SelectedIndexChanged <asp:ListBox Rows="3" Runat="server" OnSelectedIndexChanged="DoSIChanged" /> AutoPostBack (causes a delayed event to lead to an immediate round trip) TextChanged <asp:TextBox Runat="server" AutoPostBack="true" OnTextChanged="DoTextChanged" /> Überblick

517 ASP.NET Simple Dynamic Web Pages Web Forms Event Handling Web Controls
Validators User Controls Custom Controls State Management Configuration of ASP.NET Working with Visual Studio .NET Überblick


Download ppt "C# The new language for Updated by Pavel Ježek"

Similar presentations


Ads by Google