(1) c sharp introduction_basics_dot_net
TRANSCRIPT
2
TOC● (2) Introduction of C# Basics – Part I
– A Tour through other .Net Programming Languages
– C# Syntax Cornerstones
3
Challenge: Parse an Update Log● Userstory: "As an administrator I want to know the latest updates on a PC, in order to get a report of that PC's state!"
● It is needed to parse the file "Software Update.log":
2009-04-06 12:43:04 +0200: Installed "GarageBand Update" (5.0.1)
2009-04-06 12:44:34 +0200: Installed "iMovie Update" (8.0.1)
2009-07-30 13:11:28 +0200: Installed "iMovie Update" (8.0.4)
2009-04-06 12:43:31 +0200: Installed "iTunes" (8.1)
…
● How can we solve this problem?
4
Visual Basic 10 (VB 10)Imports SystemImports System.IOImports System.Collections.GenericImports System.Text.RegularExpressions
Module ProgramSub Main()
' check arguments from console If (0 < My.Application.CommandLineArgs.Count) Then Dim latestUpdates As IDictionary(Of String, String) = New SortedDictionary(Of String, String) Dim parseRex As Regex = New Regex("[^\""]*\""(?<appName>[^\""]*)\""\s*\((?<versionNo>[^\(]*)\)") ' open and check file, read a line For Each aLine As String In File.ReadAllLines(My.Application.CommandLineArgs.Item(0)) ' parse the line: e.g. 2009-04-06 12:42:58 +0200: Installed "Digital Camera Raw Compatibility Update" (2.5) Dim match As Match = parseRex.Match(aLine) If (match.Success) Then ' store the parsed data Dim appName As String = match.Groups.Item("appName").ToString() Dim versionNo As String = match.Groups.Item("versionNo").ToString() If (latestUpdates.ContainsKey(appName)) Then If (0 < String.CompareOrdinal(versionNo, latestUpdates.Item(appName))) Then latestUpdates.Item(appName) = versionNo End If Else latestUpdates.Add(appName, versionNo) End If End If Next ' output the collected data to console For Each item As KeyValuePair(Of String, String) In latestUpdates Console.WriteLine("App: {0}, Latest Update: {1}", item.Key, item.Value) Next End If End SubEnd Module
5
C++/CLI – Part I#include "stdafx.h"
using namespace System;using namespace System::IO;using namespace System::Collections::Generic;using namespace System::Text::RegularExpressions;
int main(array<String^>^ args){
// check arguments from console if (0 < args->Length) { IDictionary<String^, String^>^ latestUpdates = gcnew SortedDictionary<String^, String^>(); Regex^ parseRex = gcnew Regex("[^\\\"]*\\\"(?<appName>[^\\\"]*)\\\"\\s*\\((?<versionNo>[^\\(]*)\\)"); // open and check file, read a line for each (String^ aLine in File::ReadAllLines(args[0])) { // parse the line: e.g. 2009-04-06 12:42:58 +0200: Installed "Digital Camera Raw Compatibility Update" (2.5) Match^ match = parseRex->Match(aLine); if (match->Success) { // store the parsed data
String^ appName = match->Groups["appName"]->ToString(); String^ versionNo = match->Groups["versionNo"]->ToString(); if (latestUpdates->ContainsKey(appName)) { if (0 < String::CompareOrdinal(versionNo, latestUpdates[appName])) { latestUpdates[appName] = versionNo; } } else
6
C++/CLI – Part II{
latestUpdates->Add(appName, versionNo); } } } // output the collected data to console for each (KeyValuePair<String^, String^>^ item in latestUpdates) { Console::WriteLine("App: {0}, Latest Update: {1}", item->Key, item->Value); }
}}
7
F# 3
#lightopen Systemopen System.IOopen System.Text.RegularExpressions
if 2 >= Environment.GetCommandLineArgs().Length thenlet parseRex = new Regex(@"[^\""]*\""(?<appName>[^\""]*)\""\s*\((?<versionNo>[^\(]*)\)")
// open and check file, read the lines, parse and process the data, output the processed data to console File.ReadLines(Environment.GetCommandLineArgs().GetValue(1).ToString()) |> Seq.map(parseRex.Match) |> Seq.filter(fun theMatch -> theMatch.Success) |> Seq.sortBy(fun theMatch -> theMatch.Groups.Item("versionNo").ToString()) |> Seq.map(fun theMatch -> theMatch.Groups.Item("appName").ToString(), theMatch.Groups.Item("versionNo").ToString()) |> dict |> Seq.sortBy(fun item -> item.Key) |> Seq.iter(fun item -> printfn "App: %s, Latest Update: %s" item.Key item.Value)
8
C# 5 – Part Iusing System;using System.IO;using System.Collections.Generic;using System.Text.RegularExpressions;
public class Program{
public static void Main(string[] args){
// check arguments from consoleif (0 < args.Length){
IDictionary<string, string> latestUpdates = new SortedDictionary<string, string>();Regex parseRex = new Regex(@"[^\""]*\""(?<appName>[^\""]*)\""\s*\((?<versionNo>[^\(]*)\)");// open and check file, read a lineforeach (string aLine in File.ReadAllLines(args[0])){
// parse the line: e.g. 2009-04-06 12:42:58 +0200: Installed "Digital Camera Raw Compatibility Update" (2.5)Match match = parseRex.Match(aLine);if (match.Success){
// store the parsed datastring appName = match.Groups["appName"].ToString();string versionNo = match.Groups["versionNo"].ToString();if (latestUpdates.ContainsKey(appName))
{ if (0 < string.CompareOrdinal(versionNo, latestUpdates[appName])) { latestUpdates[appName] = versionNo; } } else
9
C# 5 – Part II { latestUpdates.Add(appName, versionNo); }
}}// output the collected data to consoleforeach (KeyValuePair<string, string> item in latestUpdates){
Console.WriteLine("App: {0}, Latest Update: {1}", item.Key, item.Value);}
}}
}
10
Common Intermediate Language (CIL, also just IL)IL_0001: ldc.i4.1 IL_0002: newarr System.StringIL_0007: stloc.s 08 // CS$0$0000IL_0009: ldloc.s 08 // CS$0$0000IL_000B: ldc.i4.0 IL_000C: ldstr "C:\Users\nludwig\Desktop\application.properties"IL_0011: stelem.ref IL_0012: ldloc.s 08 // CS$0$0000IL_0014: stloc.0 // argsIL_0015: ldc.i4.0 IL_0016: ldloc.0 // argsIL_0017: ldlen IL_0018: conv.i4 IL_0019: clt IL_001B: ldc.i4.0 IL_001C: ceq IL_001E: stloc.s 09 // CS$4$0001IL_0020: ldloc.s 09 // CS$4$0001IL_0022: brtrue IL_0154IL_0028: newobj System.Collections.Generic.SortedDictionary<System.String,System.String>..ctorIL_002D: stloc.1 // latestUpdatesIL_002E: ldstr "[ \̂"]*\"(?<appName>[ \̂"]*)\"\s*\((?<versionNo>[ \̂(]*)\)"IL_0033: newobj System.Text.RegularExpressions.Regex..ctorIL_0038: stloc.2 // parseRexIL_003A: ldloc.0 // argsIL_003B: ldc.i4.0 IL_003C: ldelem.ref IL_003D: call System.IO.File.ReadAllLinesIL_0042: stloc.s 0A // CS$6$0002IL_0044: ldc.i4.0 IL_0045: stloc.s 0B // CS$7$0003IL_0047: br IL_00EFIL_004C: ldloc.s 0A // CS$6$0002IL_004E: ldloc.s 0B // CS$7$0003IL_0050: ldelem.ref IL_0051: stloc.3 // aLineIL_0053: ldloc.2 // parseRexIL_0054: ldloc.3 // aLineIL_0055: callvirt System.Text.RegularExpressions.Regex.MatchIL_005A: stloc.s 04 // matchIL_005C: ldloc.s 04 // matchIL_005E: callvirt System.Text.RegularExpressions.Group.get_SuccessIL_0063: ldc.i4.0 IL_0064: ceq IL_0066: stloc.s 09 // CS$4$0001IL_0068: ldloc.s 09 // CS$4$0001IL_006A: brtrue.s IL_00E8IL_006D: ldloc.s 04 // matchIL_006F: callvirt System.Text.RegularExpressions.Match.get_GroupsIL_0074: ldstr "appName"IL_0079: callvirt System.Text.RegularExpressions.GroupCollection.get_ItemIL_007E: callvirt System.Object.ToStringIL_0083: stloc.s 05 // appNameIL_0085: ldloc.s 04 // matchIL_0087: callvirt System.Text.RegularExpressions.Match.get_GroupsIL_008C: ldstr "versionNo"IL_0091: callvirt System.Text.RegularExpressions.GroupCollection.get_ItemIL_0096: callvirt System.Object.ToStringIL_009B: stloc.s 06 // versionNoIL_009D: ldloc.1 // latestUpdatesIL_009E: ldloc.s 05 // appNameIL_00A0: callvirt System.Collections.Generic.IDictionary<System.String,System.String>.ContainsKeyIL_00A5: ldc.i4.0 IL_00A6: ceqIL_00A8: stloc.s 09 // CS$4$0001IL_00AA: ldloc.s 09 // CS$4$0001IL_00AC: brtrue.s IL_00DAIL_00AF: ldc.i4.0
IL_00B0: ldloc.s 06 // versionNoIL_00B2: ldloc.1 // latestUpdatesIL_00B3: ldloc.s 05 // appNameIL_00B5: callvirt System.Collections.Generic.IDictionary<System.String,System.String>.get_ItemIL_00BA: call System.String.CompareOrdinalIL_00BF: clt IL_00C1: ldc.i4.0 IL_00C2: ceq IL_00C4: stloc.s 09 // CS$4$0001IL_00C6: ldloc.s 09 // CS$4$0001IL_00C8: brtrue.s IL_00D7IL_00CB: ldloc.1 // latestUpdatesIL_00CC: ldloc.s 05 // appNameIL_00CE: ldloc.s 06 // versionNoIL_00D0: callvirt System.Collections.Generic.IDictionary<System.String,System.String>.set_Item IL_00D8: br.s IL_00E7IL_00DB: ldloc.1 // latestUpdatesIL_00DC: ldloc.s 05 // appNameIL_00DE: ldloc.s 06 // versionNoIL_00E0: callvirt System.Collections.Generic.IDictionary<System.String,System.String>.Add IL_00E9: ldloc.s 0B // CS$7$0003IL_00EB: ldc.i4.1 IL_00EC: add IL_00ED: stloc.s 0B // CS$7$0003IL_00EF: ldloc.s 0B // CS$7$0003IL_00F1: ldloc.s 0A // CS$6$0002IL_00F3: ldlen IL_00F4: conv.i4 IL_00F5: clt IL_00F7: stloc.s 09 // CS$4$0001IL_00F9: ldloc.s 09 // CS$4$0001IL_00FB: brtrue IL_004CIL_0101: ldloc.1 // latestUpdatesIL_0102: callvirt System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.String,System.String>>.GetEnumeratorIL_0107: stloc.s 0C // CS$5$0004IL_0109: br.s IL_012FIL_010B: ldloc.s 0C // CS$5$0004IL_010D: callvirt System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<System.String,System.String>>.get_CurrentIL_0112: stloc.s 07 // itemIL_0115: ldstr "App: {0}, Latest Update: {1}"IL_011A: ldloca.s 07 // itemIL_011C: call System.Collections.Generic.KeyValuePair<System.String,System.String>.get_KeyIL_0121: ldloca.s 07 // itemIL_0123: call System.Collections.Generic.KeyValuePair<System.String,System.String>.get_ValueIL_0128: call System.Console.WriteLine IL_012F: ldloc.s 0C // CS$5$0004IL_0131: callvirt System.Collections.IEnumerator.MoveNextIL_0136: stloc.s 09 // CS$4$0001IL_0138: ldloc.s 09 // CS$4$0001IL_013A: brtrue.s IL_010BIL_013C: leave.s IL_0152IL_013E: ldloc.s 0C // CS$5$0004IL_0140: ldnull IL_0141: ceq IL_0143: stloc.s 09 // CS$4$0001IL_0145: ldloc.s 09 // CS$4$0001IL_0147: brtrue.s IL_0151IL_0149: ldloc.s 0C // CS$5$0004IL_014B: callvirt System.IDisposable.Dispose IL_0151: endfinally
11
What is the C# programming language?● C# is standardized in ECMA-334.
● C# blends features of C++, Java and other popular languages.– Without C# being based on Java, .Net would not have been a success!
● A CLS compliant language, ECMA and ISO/IEC standard.
● Major platform is Windows (compilers and CLR from MS).
12
C# Core Features● Multiparadigm language.
● Static typing by default.
● C-style syntax with extensions.
● CTS is the first class type system.
● C# is popular and evolving.– Relatively short innovation cycles. Learned stuff gets stale early (~two years).
● C# is relatively simple to learn.– It is basically pointer free. (We could use pointers. The CTS doesn't use pointers.)
– It doesn't use manual memory management, the runtime has a garbage collector.
13
Structure of a C# Console Application
// Program.csusing System;
namespace ConsoleApplication{
public class Program{
// The execution of a program always starts in the method Main().public static void Main(string[] args){
Console.WriteLine("Hello World!");}
}}
14
Code Snippets● Hence we'll begin using snippets as code examples, i.e. no Main() etc.!
● In the end no fully runnable program code will be shown in upcoming lectures!
// Program.csusing System;
namespace ConsoleApplication{
public class Program{
public static void Main(string[] args){
Console.WriteLine("Hello World!");}
}}
Console.WriteLine("Hello World!");
15
C# as a compiled Language● C# reserves symbols for its grammar, these are called keywords.
● Syntax versus Semantics:
– Both statements do not mean the same, but the syntax is similar!
– Locals need to be initialized, uninitialized fields have default values.
● Compile time errors versus run time errors:
– Both statements are ok for the compiler.
● But the last one throws a DivisionByZeroException at run time.
int count = 2;
count = 2;
int zero = 0;int oddResult = 42/zero;
16
C# Syntax Cornerstones – Part I – Imperative Elements
● Basic elements: expressions, statements, blocks. They can be freely formatted.– Imperative programming: Statements and blocks are executed sequentially.
– The order of execution of expressions is strictly defined in C#!
● The most elementary statements are variable definitions.– Variable definitions make variables applicable in the code.
– By default, variables need to be typed on definition, this is called static typing.
● Implicit and dynamic typing is also possible, but we stick to explicit static typing in this course.
● Besides definition, variables can be initialized and assigned to.– Initialization gives initial values to a variable.
– Assignment sets a variable to a new value.
if (answerIsOk) {Console.WriteLine("Result: "+(3 + 4));
}
int age = 19;
age = 25;
double width = 32.8;
17
C# Syntax Cornerstones – Part II – Types● Primitive types are integrated types, whose objects can be created with literals.
– Simple value integral types: int, long (etc.).
– Simple value float types: float, double (etc.).
– Simple value boolean type: bool.
– Simple value character type: char.
– Reference text type: string. (an alias C# keyword for the .Net type System.String)
– We can create compile time constants (const) of primitive type.
● There exist value types (e.g. int) and reference types (e.g. string).– Variables of reference type are often simply called references.
● Explicit type conversion:– Explicit conversions are done with explicit casts or the as operator.
– Explicit conversions can be done safely with checked expressions and contexts.
– The type System.Convert (various types) and the methods ToString()/Parse() (string).
// Conversion with cast:int i = (int)2.78;
// Conversion with as:string text = choice as string;
18
C# Syntax Cornerstones – Part III – Identifiers and Comments
• C# uses case sensitive identifiers, we have to obey common conventions.
– aString is not the same identifier as aStRiNg!
– We've to use a common notation (e.g. camelCase or PascalCase) as convention!
– Language specific characters can be used (e.g. umlauts) as well as the underscore.
– C# keywords mustn't be used as identifiers.
• Comments can be applied everywhere in code. We should exploit comments!
• The usage and definition of methods will be discussed later.
– Methods are .Net's pendant of functions/member functions in other languages.
• In the next slides we're going to understand the most important operators in C#.
/* commented */ /** commented */ // commented /// commented (triple slash)
19
Operator Notations – Arity● Binary operators
● Unary operators
● Ternary operator
// Addition as binary operator:int sum = 2 + 3;
// Increment as unary operator:int i = 1;++i; // Increments i (the result is 2).
// The conditional operator is the only ternary operator:int i = 2;int j = 3;string answer = (i < j) ? "i less than j" : "i not less than j";
20
Operator Notations – Placement● Prefix operators
● Postfix operators
● Infix operators
// Negation as prefix operator:bool succeeded = !failed;
// Increment as postfix operator:int result = item++;
// Addition as infix operator:int sum = 2 + 3;
21
Mathematical Operators● Binary +, - and *, / are known form elementary mathematics.
– Attention: Integer division yields an integer result!
– The result of the division by 0 results in a run time error.● A DivisionByZeroException will be thrown.
● Unary – and + as sign-operators.
● Somewhat special: ++/-- and %
● Math.Log(), Math.Pow() and other operations in the class Math.
● Bit operations work with integers as arguments and result in integers.– Operators: ^, |, &, ~, <<, >>
22
Other Operators and Operator Overloading● Assignment and combined assignment.
– Operators: =, +=, *=, /= etc.
– Operators: &=, |=, ^=, <<=, >>=
● Concatenation of strings with the operators + and +=.– But: strings are still immutable!
● Important extra operators:– Operators: [], (), ?:, ??, new, is, as, typeof
– Operators: ., ::
– Operators: *, ->, sizeof
– Operators: =>
● C# permits to redefine (overload) operators for user defined types UDT.
int i = 12;i = i + 2; // (i = 14) Add and assign.i += 2; // (i = 16) Add-combined assignment.
23
Logical Operators● Used to compare values and combine boolean results.
– Comparison: ==, !=, <, >, <=, >=
– Combination: &&, ||, !
– Logical operators return boolean results, not integral results.
● && (logical and) and || (logical or) support short circuit evaluation.
● Logical operators are applied in conditional expressions for control structures (branches and loops).
// The mathematic boolean expression a = b and c = b: // Okif (a == b && c == b) { /* pass */ }// Wrong!if (a && b == c) { /* pass */ }
24
Precedence, Associativity and Order of Execution● Precedence and precedence groups.
– Some operators have the same precedence and make up a precedence group.
– As operator priority in maths, precedence is controllable with parentheses.
● Associativity defines evaluation among expressions of the same precedence.– Associativity is defined as a "direction".
– Associativity is controllable with parentheses as well.
● The order of execution within expressions is strictly defined in C#.– The order is from left to right and from inner to outer.
int i = 0;Console.WriteLine("{0} {1}", i++, i);// >0 1 → Always this result …// Never 0 0!