c# in depth

126
1 Copyright © 2012 Retalix | | Arnon Axelrod C# IN DEPTH

Upload: arnon-axelrod

Post on 10-Feb-2017

232 views

Category:

Software


1 download

TRANSCRIPT

Page 1: C# in depth

1 Copyright © 2012 Retalix ||

Arnon Axelrod

C# IN DEPTH

Page 2: C# in depth

2 Copyright © 2012 Retalix |

About me

Page 3: C# in depth

3 Copyright © 2012 Retalix |

About youAlready familiar with:? Reflection Generics Lambdas Linq dynamic async/await

Page 4: C# in depth

4 Copyright © 2012 Retalix |

Anders Hejlsberg

C♯

Page 5: C# in depth

5 Copyright © 2012 Retalix |

Today

• Background• C# 1• C# 2

• C# 3• C# 4• C# 5

(+Roslyn)

Page 6: C# in depth

6 Copyright © 2012 Retalix |

Assuming you already know: If/switch/for/foreach/while

Local variables, class variables, static variables, parameters public, private, protected, internal

Classes, interfaces, inheritance Virtual, overload, static methods

Page 7: C# in depth

7 Copyright © 2012 Retalix |

Basic terms

Page 8: C# in depth

8 Copyright © 2012 Retalix |

Class vs. Object

Class Objects

Page 9: C# in depth

9 Copyright © 2012 Retalix |

References / Pointers

class Class2(){ int i2 = 3; byte b2 = 4; char c = 'a'}

class Class1(){ int i = 5; bool b = false; public Class2 c2;}

i b c2 i2 b2 c5 false 0x000

0… 3 4 ‘a’

0x1234

0x4567

x = new Class1()y = new Class2();x.c2 = y;

0x4567

Reference Object

Page 10: C# in depth

10 Copyright © 2012 Retalix |

Stack vs. Heap

Stack• Local variables

– Can reference objects on the heap

• Parameter values• Return address• LIFO

Heap• Objects

– Containing fields• Arrays• Allocated on demand

(new)• Freed automatically

(GC)

Page 11: C# in depth

11 Copyright © 2012 Retalix |

Static variables• Live for the entire lifespan of the process• Fixed size• Can reference objects on the heap

Page 12: C# in depth

12 Copyright © 2012 Retalix |

Value types vs. Reference types

Value types• What?

– byte, char, int, etc.– Enums– Structs

• Where?– Stack– Static– Fields (inside objects)

• Assignment (a=b)– Copy

Reference types• What?

– Class objects• string

– Arrays• Where?

– Heap• Assignment (a=b)

– aliasing

Page 13: C# in depth

13 Copyright © 2012 Retalix |

Value types & Reference types - common Can contain fields

Value types References to other Reference Types

Can contain methods Can implement interfaces Can have constructors Can have nested type declarations

Page 14: C# in depth

14 Copyright © 2012 Retalix |

Naming scopes• Namespaces• Private, public, internal, protected• Nested types

Relevant only

at compile

time!

Page 15: C# in depth

15 Copyright © 2012 Retalix |

The .Net Framework

Page 16: C# in depth

16 Copyright © 2012 Retalix |

The .NET Framework

Base Class Library

Common Language Specification

Common Language Runtime

ADO.NET: Data and XML

VB C++ C#Visual Studio.N

ET

ASP.NET: Web ServicesAnd Web Forms

JScript …

Windowsforms

Page 17: C# in depth

17 Copyright © 2012 Retalix |

.Net

C# Compiler

CLR

Native code

JIT Compiler

MSIL

Page 18: C# in depth

18 Copyright © 2012 Retalix |

CLRThe JIT Compilervoid Main(){ Foo(); Bar();}

IL of Foo

void Foo(){ ... Bar(); ....}

void Bar(){ ...}

IL of Bar

Methods tableFooBar…

JIT Compiler

JIT Compile(Foo)

JIT Compile(Bar)

Machine code for Foo

Machine code for Bar

Page 19: C# in depth

19 Copyright © 2012 Retalix |

Garbage Collector Allocation in O(1) Automatic De-allocation

Graph traversal Automatic De-

fragmentation On a background thread

Next free position

Page 20: C# in depth

20 Copyright © 2012 Retalix |

CLR 4.5

CLR 4.0

CLR 2.0

CLR 1.0/1.1

.Net/C# evolutionC# 1.0

• Managed Code

C# 2.0

• Generics

C# 3.0

• Linq

C# 4.0

• Dynamic

C# 5.0

• Async/Await

Future

• Compiler as a service

.Net FX 1.0/1.1

.Net FX 2.0

.Net FX 3.0

.Net FX 3.5

.Net FX 4.0

.Net FX 4.5

Page 21: C# in depth

21 Copyright © 2012 Retalix |

The Compiler

Page 22: C# in depth

22 Copyright © 2012 Retalix |

The Compiler pipeline

Lexical Analyzer

Lexical Analyzer

Lexical Analyzer

Parser

Parser

Parser

Semantics analyzer / Binder

ILEmitter

Page 23: C# in depth

23 Copyright © 2012 Retalix |

using System;

// commentpublic class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

Lexical AnalyzerKeywordIdentifie

rPunctuato

rComment (ignore)Keyword KeywordIdentifie

rPunctuator Keyword Keyword KeywordIdentifie

rPunctuato

rPunctuato

rPunctuator Identifie

rPunctuato

rIdentifie

rPunctuato

r String literalPunctuator

PunctuatorPunctuato

rPunctuator

Page 24: C# in depth

24 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserCompilation-unit

Using-namespace-directive

Class-declaration

Page 25: C# in depth

25 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserClass-declaration

Class-modifier

IdentifierClass-body

Page 26: C# in depth

26 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserClass-body

Class-member-declarations

Page 27: C# in depth

27 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserClass-member-declarations

Method-declaration

Page 28: C# in depth

28 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserMethod-declaration

Method-header

Method-body

Page 29: C# in depth

29 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserMethod-body

Statements-list

Statement

Page 30: C# in depth

30 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

Parserstatement

Expression

Invocation-expression

Page 31: C# in depth

31 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserInvocation-expression

Primary-expression

Argument-list

Page 32: C# in depth

32 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserPrimary-expression

Member-access

Primary-expression

Identifier

Page 33: C# in depth

33 Copyright © 2012 Retalix |

using System;

public class Program{ public static void Main() { Console.WriteLine("Hello, World"); }}

ParserPrimary-expression

Simple-name

identifier

Page 34: C# in depth

34 Copyright © 2012 Retalix |

C# 1.0

Page 35: C# in depth

35 Copyright © 2012 Retalix |

Static memory

Reflection

Methods Table (MyClass)MetadataToString()Equals()MyVirtualMethod()…

MyClass MetadataNameDerived types…FieldsMethods…

Instance 1 of MyClass

Methods tableInstance variables…

Instance 2 of MyClass

Methods tableInstance variables…

Instance 3 of MyClass

Methods tableInstance variables…

Page 36: C# in depth

36 Copyright © 2012 Retalix |

Demo - Reflection

Page 37: C# in depth

37 Copyright © 2012 Retalix |

Demo - Attributes

Page 38: C# in depth

38 Copyright © 2012 Retalix |

Demo – Finalize and IDisposable

Page 39: C# in depth

39 Copyright © 2012 Retalix |

Demo - IEnumerable

Page 40: C# in depth

40 Copyright © 2012 Retalix |

Demo – Delegates & Events

Page 41: C# in depth

41 Copyright © 2012 Retalix |

Demo - params

Page 42: C# in depth

42 Copyright © 2012 Retalix |

Demo – Explicit & Implicit interface implementations

Page 43: C# in depth

43 Copyright © 2012 Retalix |

C# 2.0

Page 44: C# in depth

44 Copyright © 2012 Retalix |

Generics• The problem in .Net 1.0/1.1:

ArrayList list = new ArrayList();list.Add(1);list.Add(2);list.Add("3"); // do you really want to allow that?!

int sum = 0;foreach (object element in list){ sum += (int) element; // is it safe?!}

Page 45: C# in depth

45 Copyright © 2012 Retalix |

Generics• Solution in .Net 1.0/1.1:

• MyIntList, MyStringList, MyStudentList, …• Still Boxing and Unboxing…

MyIntList list = new MyIntList();list.Add(1);list.Add(2);list.Add(3); // list.Add(“4”); - compilation error!

int sum = 0;foreach (int element in list){ sum += element;}

Page 46: C# in depth

46 Copyright © 2012 Retalix |

Generics• Type safety• Reusable• Optimized

– Jitted once for all reference types– Jitted once for each value type (no boxing and unboxing!)

• Applicable for class, struct, interface, Delegate, method

• Can have constraints (more on that later)• Handled by the compiler and the CLR together

Page 47: C# in depth

47 Copyright © 2012 Retalix |

GenericsAutomatic type inference• Example:

int i = 3;

MyMethod<int>(i);

Is equivallent to:MyMethod(i);

• Type arguments for a class can be inferred by the arguments passed to the constructor

Page 48: C# in depth

48 Copyright © 2012 Retalix |

Generics• typeof(T) provides the real type using reflection• default(T) provides the default value of a value

type or null for a reference type

Page 49: C# in depth

49 Copyright © 2012 Retalix |

Demo - Generics

Page 50: C# in depth

50 Copyright © 2012 Retalix |

Generics - constraints• struct / class• Primary type and multiple interfaces• new()

Page 51: C# in depth

51 Copyright © 2012 Retalix |

Demo: Generics with constraints

Page 52: C# in depth

52 Copyright © 2012 Retalix |

Nullable<T>• int i = null; // syntax error

• int? is a syntactic sugar for System.Nullable<int>

• struct – no boxing/unboxing

Page 53: C# in depth

53 Copyright © 2012 Retalix |

Demo – Nullable<T>

Page 54: C# in depth

54 Copyright © 2012 Retalix |

Action, Func, PredicateDelegates also support Generics• delegate void Action()

delegate void Action<T>(T arg1);…delegate void Action<T1, T2, T3, …, T8>(T1 arg1, T2 arg2, …, T8 arg8);

• delegate TResult Func<TResult>();delegate TResult Func<T, TResult>(T arg);…delegate TResult Action<T1, T2, …, T8, TResult>(T1 arg1, T2 arg2, …, T8 arg8);

• delegate bool Predicate<T>(T obj);

Page 55: C# in depth

55 Copyright © 2012 Retalix |

Demo – Anonymous methods

Page 56: C# in depth

56 Copyright © 2012 Retalix |

Demo – Iterator blocks

Page 57: C# in depth

57 Copyright © 2012 Retalix |

Demo – Partial types

Page 58: C# in depth

58 Copyright © 2012 Retalix |

C# 3

Page 59: C# in depth

59 Copyright © 2012 Retalix |

Demo – type inference (var)

Page 60: C# in depth

60 Copyright © 2012 Retalix |

Demo – initializer and auto-properties

Page 61: C# in depth

61 Copyright © 2012 Retalix |

Demo – Anonymous types

Page 62: C# in depth

62 Copyright © 2012 Retalix |

Demo – Lambda expressions

Page 63: C# in depth

63 Copyright © 2012 Retalix |

Extension methodsBack to basics…• In the beginning there was ‘C’…• Then there was “C with classes” (C++ to C

compiler)• Then we forgot we can live without classes

What is “this”?

Page 64: C# in depth

64 Copyright © 2012 Retalix |

Demo – “this”

Page 65: C# in depth

65 Copyright © 2012 Retalix |

Extension methods - Motivationclass MyClass{ //...} class SomeLibraryThatICannotTouch{ MyClass CreateMyClass() { return new MyClass(); }} class MyDerivedClass : MyClass

{ public void AddedFunctionality() { … }}

var myObject = SomeLibraryThatICannotTouch.CreateMyClass();myObject.AddedFunctionality();

Compilation error!

Page 66: C# in depth

66 Copyright © 2012 Retalix |

Extension methods

public static MyExtensionClass{ public static void MyExtensionMethod(MyClass

myObject, int i) { // Do something… }}

var myObject = SomeLibraryThatICannotTouch.CreateMyClass();

MyExtensionClass.MyExtensionMethod(myObject, 3);

Page 67: C# in depth

67 Copyright © 2012 Retalix |

Extension methods

public static MyExtensionClass{ public static void MyExtensionMethod(this

MyClass myObject, int i) { // Do something… }}

var myObject = SomeLibraryThatICannotTouch.CreateMyClass();

myObject.MyExtensionMethod(3);

Page 68: C# in depth

68 Copyright © 2012 Retalix |

Extension methodsThisIs().Some().Expression().MyExtensionMethod(3)

Is equivalent to:

ClassName.MyExtensionMethod(ThisIs().Some().Expression(), 3)

This is not an expression – only a naming scope

Page 69: C# in depth

69 Copyright © 2012 Retalix |

Extension methodsPoints to remember: Extension methods are really static methods behind

the scenes Can only access public members Both the class and the method must be declared as

static Only the first argument can be prefixed with the ‘this’

keyword To access the extension method you have to import

the namespace (using namespace)

Page 70: C# in depth

70 Copyright © 2012 Retalix |

Demo – Extension methods

Page 71: C# in depth

71 Copyright © 2012 Retalix |

Linq – Language Integrated Queries

Page 72: C# in depth

72 Copyright © 2012 Retalix |

System.Linq.Enumerable IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,

Func<TSource, bool> predicate);

bool Contains<TSource>(this IEnumerable<TSource> source, TSource value);

int Count<TSource>(this IEnumerable<TSource> source);

TSource First<TSource>(this IEnumerable<TSource> source);TSource Last<TSource>(this IEnumerable<TSource> source);

decimal Sum(this IEnumerable<decimal> source);

IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);

IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);

Page 73: C# in depth

73 Copyright © 2012 Retalix |

Query Expressions• Language integrated query syntaxfrom itemName in srcExpr( from itemName in source| where condition| join itemName in srcExpr on keyExpr equals keyExpr| let itemName = selExpr| orderby (keyExpr (ascending | descending)?)* )*( select expr | group expr by key )[ into itemName query ]?

Page 74: C# in depth

74 Copyright © 2012 Retalix |

from c in customerswhere c.State == "WA"select new { c.Name, c.Phone };

customers.Where(c => c.State == "WA").Select(c => new { c.Name, c.Phone });

Query Expressions• Queries translate to method invocations

– Where, Select, SelectMany, OrderBy, GroupBy

Page 75: C# in depth

75 Copyright © 2012 Retalix |

Demo – Linq to Object

Page 76: C# in depth

76 Copyright © 2012 Retalix |

Expression Trees

Page 77: C# in depth

77 Copyright © 2012 Retalix |

Expression Trees - motivation• Linq to SQL / Entity Framework

from student in StudentsTablewhere student.FirstName.Length == 4orderby student.Grade descendingselect new {student.LastName, student.Grade};

Do we need to retrieve

the entire table?!

Page 78: C# in depth

78 Copyright © 2012 Retalix |

Expression Trees((16 + 5 x 4) / 9) + 17 x 3

Page 79: C# in depth

79 Copyright © 2012 Retalix |

Demo – System.Linq.Expressions (BatchFileCreator)

Page 80: C# in depth

80 Copyright © 2012 Retalix |

Demo – Expression<Tdelegate>.Compile()

(DynamicMethodCreatorDemo)

Page 81: C# in depth

81 Copyright © 2012 Retalix |

IQueryable<T>interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable{} public interface IQueryable : IEnumerable

{ Type ElementType { get; } Expression Expression { get; } IQueryProvider Provider { get; }} public interface IQueryProvider

{ IQueryable CreateQuery(Expression expression); IQueryable<TElement> CreateQuery<TElement>(Expression expression); object Execute(Expression expression); TResult Execute<TResult>(Expression expression);}

Page 82: C# in depth

82 Copyright © 2012 Retalix |

System.Linq.Queryable IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source,

Expression<Func<TSource, bool>> predicate);

bool Contains<TSource>(this IQueryable<TSource> source, TSource item);

int Count<TSource>(this IQueryable<TSource> source);

TSource First<TSource>(this IQueryable<TSource> source);TSource Last<TSource>(this IQueryable<TSource> source);

decimal Sum(this IQueryable<decimal> source);

IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector);

IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);

IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);

Page 83: C# in depth

83 Copyright © 2012 Retalix |

Demo – Entity Framework

Page 84: C# in depth

84 Copyright © 2012 Retalix |

C# 4

Page 85: C# in depth

85 Copyright © 2012 Retalix |

Optional and Named Arguments

Page 86: C# in depth

86 Copyright © 2012 Retalix |

Optional & Named Parameterspublic StreamReader OpenTextFile( string path, Encoding encoding, bool detectEncoding, int bufferSize);

public StreamReader OpenTextFile( string path, Encoding encoding, bool detectEncoding);

public StreamReader OpenTextFile( string path, Encoding encoding);

public StreamReader OpenTextFile( string path);

Primary method

Secondary overloads

Call primary with default

values

Page 87: C# in depth

87 Copyright © 2012 Retalix |

public StreamReader OpenTextFile( string path, Encoding encoding, bool detectEncoding, int bufferSize);

public StreamReader OpenTextFile( string path, Encoding encoding = null, bool detectEncoding = true, int bufferSize = 1024);

Optional & Named ParametersOptional parameters

OpenTextFile("foo.txt", Encoding.UTF8);OpenTextFile("foo.txt", Encoding.UTF8, bufferSize: 4096);

Named argument

OpenTextFile( bufferSize: 4096, path: "foo.txt", detectEncoding: false);

Named arguments must be last

Non-optional must be specified

Arguments evaluated in order

written

Named arguments can appear in any

order

Page 88: C# in depth

88 Copyright © 2012 Retalix |

Overload resolution• If two signatures are equally good, one that does

not omit optional parameters is preferred.

– A signature is applicable if all its parameters are either optional or have exactly one corresponding argument (by name or position) in the call which is convertible to the parameter type.

1. M( string s, int i = 1 );2. M( object o );3. M( int i , string s = “Hello” );4. M( int i );

M( 5 ); // 4, 3, & 2 are applicable, // but 4 is the best match.

Page 89: C# in depth

89 Copyright © 2012 Retalix |

Demo – Optional and named arguments

Page 90: C# in depth

90 Copyright © 2012 Retalix |

Dynamic

Page 91: C# in depth

91 Copyright © 2012 Retalix |

PythonBinder

RubyBinder

COMBinder

JavaScriptBinder

ObjectBinder

.NET Dynamic Programming

Dynamic Language Runtime (DLR)Expression Trees Dynamic

Dispatch Call Site Caching

IronPython IronRuby C# VB.NET Others…

Page 92: C# in depth

92 Copyright © 2012 Retalix |

Dynamically Typed Objectsobject calc = GetCalculator();int sum = calc.Add(10, 20);

object calc = GetCalculator();Type calcType = calc.GetType();object res = calcType.InvokeMember("Add",

BindingFlags.InvokeMethod, null, new object[] { 10, 20 } );

int sum = Convert.ToInt32(res);

dynamic calc = GetCalculator();int sum = calc.Add(10, 20);

Statically typed to be dynamic

Dynamic method invocationDynamic

conversion

Syntax Error!

Page 93: C# in depth

93 Copyright © 2012 Retalix |

The Dynamic Type• With dynamic you can “do things” that are resolved

only at runtime.• Any object can be implicitly converted to dynamic.

( object dynamic )• Any dynamic Type can be assignment conversion to

any other type. ( dynamic object )

dynamic x = 1; // implicit conversionint num = x; // assignment conversion

Page 94: C# in depth

94 Copyright © 2012 Retalix |

Dynamic with Plain Objects• The operation will be dispatched using reflection

on its type and a C# “runtime binder” which implements C#’s lookup and overload resolution semantics at runtime.

dynamic d1 = new Foo(); // assume that the actual type Foo of d1 dynamic d2 = new Bar(); // is not a COM type and does not string s; // implement IDynamicObject

d1.M(s, d2, 3, null); // dispatched using reflection

Page 95: C# in depth

95 Copyright © 2012 Retalix |

Overload Resolution with Dynamic Arguments

• If the receiver of a method call is of a static type, overload resolution can still happen at runtime. This can happen if one or more of the arguments have the type dynamic.

public static class Math{ public static decimal Abs(decimal value); public static double Abs(double value); public static float Abs(float value); ...}

dynamic x = 1.75;dynamic y = Math.Abs(x);

Method chosen at run-time:

double Abs(double x)

Page 96: C# in depth

96 Copyright © 2012 Retalix |

Generics => Dynamic

public T Square<T>( T x ){

return x*x;}public T SumOfSquares<T>( T x , T y ){ return Square(x) + Square(y);}

public dynamic Square( dynamic x ){

return x*x;}public dynamic SumOfSquares( dynamic x , dynamic

y ){ return Square(x) + Square(y);}

Page 97: C# in depth

97 Copyright © 2012 Retalix |

Dynamic Limitations• Dynamic lookup will not be able to find extension

methods.

• Anonymous functions cannot appear as arguments to a dynamic method call. dynamic collection = ...;var result = collection.Select(e => e + 5);

Note:1. If the Select method is an extension method, dynamic lookup

will not find it.

2. Even if it is an instance method, the above does not compile, because a lambda expression cannot be passed as an argument to a dynamic operation.

Page 98: C# in depth

98 Copyright © 2012 Retalix |

Demo - Dynamic

Page 99: C# in depth

99 Copyright © 2012 Retalix |

Co- & Contra- Variance

Page 100: C# in depth

100

Copyright © 2012 Retalix |

Covariance vs. Contra variance • Covariance (Out):

Is the ability to use a more derived type than that specified.

• Contra variance (in):Is the ability to use a less derived type

delegate Animal MyDel();MyDel del = TestMethod; // Co - Variance (Out): Return Dog as Animal, Ok. public Dog TestMethod(){ ... }

delegate void MyDel( Dog dog );MyDel del = TestMethod; del( new Dog() ); // Contra-Variance (In): Arg Dog as Animal, Ok.public void TestMethod( Animal animal){ ... }

Page 101: C# in depth

101

Copyright © 2012 Retalix |

Covariance & Generic• What you think?

• Allowing an int to be inserted into a list of strings and subsequently extracted as a string. This would be a breach of type safety.

IList<string> strings = new List<string>();IList<object> objects = strings;

IList<string> strings = new List<string>();IList<object> objects = strings;

// IEnumerable<T> is read-only and therefore safely// co-variant (out).

IEnumerable<object> objects = strings;

Page 102: C# in depth

102

Copyright © 2012 Retalix |

Covariance

void Process(object[] objects) { … }

string[] strings = GetStringArray();Process(strings);

void Process(object[] objects) { objects[0] = "Hello"; // Ok objects[1] = new Button(); // Exception!}

List<string> strings = GetStringList();Process(strings);

void Process(IEnumerable<object> objects) { … }

.NET arrays are co-variant

…but not safelyco-variant

Before .Net 4.0, generics have been invariant

void Process(IEnumerable<object> objects) { // IEnumerable<T> is read-only and // therefore safely co-variant}

C# 4.0 supports safe co- and

contra-variance

Page 103: C# in depth

103

Copyright © 2012 Retalix |

Safe Covariance (Out)public interface IEnumerable<T>{ IEnumerator<T> GetEnumerator();}

public interface IEnumerator<T>{ T Current { get; } bool MoveNext();}

public interface IEnumerable<out T>{ IEnumerator<T> GetEnumerator();}

public interface IEnumerator<out T>{ T Current { get; } bool MoveNext();}

out = Co-variantOutput positions only

IEnumerable<string> strings = GetStrings();IEnumerable<object> objects = strings;

Can be treated asless derived

Page 104: C# in depth

104

Copyright © 2012 Retalix |

public interface IComparer<T>{ int Compare(T x, T y);}

public interface IComparer<in T>{ int Compare(T x, T y);}

Safe Contra Variance (In)

IComparer<object> objComp = GetComparer();IComparer<string> strComp = objComp;

in = Contra-variantInput positions only

Can be treated asmore derived

Page 105: C# in depth

105

Copyright © 2012 Retalix |

Variance in C# 4.0• Supported for interface and delegate types

– E.g. this doesn’t work:

List<Person> list = new List<Employee>();

• Value types are always invariant– IEnumerable<int> is not IEnumerable<object>– Similar to existing rules for arrays

• Ref and Out parameters need invariant type

Page 106: C# in depth

106

Copyright © 2012 Retalix |

Variance in .NET Framework 4.0

System.Collections.Generic.IEnumerable<out T>System.Collections.Generic.IEnumerator<out T>System.Linq.IQueryable<out T>System.Collections.Generic.IComparer<in T>System.Collections.Generic.IEqualityComparer<in T>System.IComparable<in T>

Interfaces

System.Func<in T, …, out R>System.Action<in T, …>System.Predicate<in T>System.Comparison<in T>System.EventHandler<in T>

Delegates

Page 107: C# in depth

107

Copyright © 2012 Retalix |

Covariance and Contra-varianceNotes:• Works only for Generic delegates and interfaces

(not classes!)– E.g. this doesn’t work:

List<Person> list = new List<Employee>();

• Works only for Reference types (no Value types!)– E.g. this doesn’t work:

IEnumerable<Object> objects = new List<int>();

Page 108: C# in depth

108

Copyright © 2012 Retalix |

Demo - Vairance

Page 109: C# in depth

109

Copyright © 2012 Retalix |

C# 5

Page 110: C# in depth

110

Copyright © 2012 Retalix |

ASYNC & AWAIT

Page 111: C# in depth

111

Copyright © 2012 Retalix |

Terminology• Multi-core• Multi-threading• Parallelism (e.g. Parallel.ForEach)• Concurrency

– Can be single threaded!

CPU Bound

I/O Bound

async & await

Page 112: C# in depth

112

Copyright © 2012 Retalix |

Problem• Many applications need to perform concurrent

tasks and leave the UI responsive• Writing Concurrent code is cumbersome• The trend is to move most Business Logic to the

server side (WCF, REST, HTTP…)

Page 113: C# in depth

113

Copyright © 2012 Retalix |

Synchronous vs. asynchronous• var data = DownloadData(...);• ProcessData(data);

var future = DownloadDataAsync(...); future.ContinueWith(data => ProcessData(data));

DownloadDataAsync ProcessData

STOP

ProcessDataDownloadData

Page 114: C# in depth

114

Copyright © 2012 Retalix |

Synchronous vs. asynchronous• var data = DownloadData(...);• ProcessData(data);

var future = DownloadDataAsync(...); future.ContinueWith(data => ProcessData(data));

DownloadDataAsync ProcessData

STOP

ProcessDataDownloadData

STOP

Page 115: C# in depth

115

Copyright © 2012 Retalix |

Problem Solution 1 – Blocking Problem: UI is “dead” throughout the process Solution 2 – Background thread Problem – need to sync to the UI thread for

updating the UI. Thread safety is a big concern Solution 3 – Use callbacks/events Problem – makes the code fragmented and hard

to follow

Page 116: C# in depth

116

Copyright © 2012 Retalix |

The Task/Task<Tresult> classes• Abstraction for a unit of work• Task.Factory.StartNew / Task.Run• Task.Wait• TResult Task.Result• Task.ContinueWith(…)

Page 117: C# in depth

117

Copyright © 2012 Retalix |

The Await keyword• Syntax:await <expression of type Task>

var result = await <expression of type Task<TResult>>

• result is of type TResult (and not Task<TResult>!)var task = <expression of type Task<TResult>>

var result = await task;

• Yields control to the main thread until the task is completed

Page 118: C# in depth

118

Copyright © 2012 Retalix |

The Async keyword• Return type must be one of: void, Task or Task<TResult>

• Allows the use of the async keyword inside the method

• return TResult (not Task<TResult>!)• The compiler breaks the method in a manner

similar to the Iterator block transformation, while each call to MoveNext() updates the current Awaiter to the method that will act as the continuation

Page 119: C# in depth

119

Copyright © 2012 Retalix |

async & awaitpublic async Task<XElement> GetXmlAsync(string url) { var client = new HttpClient(); var response = await client.GetAsync(url); var text = response.Content.ReadAsString(); return XElement.Parse(text);}

public Task<XElement> GetXmlAsync(string url) { var tcs = new TaskCompletionSource<XElement>(); var client = new HttpClient(); client.GetAsync(url).ContinueWith(task => { var response = task.Result; var text = response.Content.ReadAsString(); tcs.SetResult(XElement.Parse(text)); }); return tcs.Task;}

Page 120: C# in depth

120

Copyright © 2012 Retalix |

GetAwaiter• await can be used with any type that has a GetAwaiter() method (or even extension method) – not just Task<T>

• The minimum required is:– INotifyCompletion:

• OnCompleted(Action handler)

– bool IsCompleted { get; }T GetResult()

Page 121: C# in depth

121

Copyright © 2012 Retalix |

TaskCompletionSource<TResult>• Represents the “producer” of the task’s result• API:

– SetResult(TResult result)

– SetException(Exception ex)

– SetCanceled()

– Task<TResult> Task { get; }

• Normally you don’t use it directly (Task.Factory.Start is the usual way)

• Helpful if you’re implementing GetAwaiter()

Page 122: C# in depth

122

Copyright © 2012 Retalix |

Demo – async & await

Page 123: C# in depth

123

Copyright © 2012 Retalix |

C# vNext

Page 124: C# in depth

124

Copyright © 2012 Retalix |

Project “Roslyn” – Compiler as a Service

Page 125: C# in depth

125

Copyright © 2012 Retalix |

Class

Field

public Foo

private

stringX

The Roslyn project

CompilerCompilerSource code

Source code

SourceFile

Source code

Source code

.NET Assembly

Meta-programming Read-Eval-Print Loop

LanguageObject Model DSL Embedding

Page 126: C# in depth

126

Copyright © 2012 Retalix |

Roslyn APIs

Language Service

Compiler APIs

Compiler Pipeline

Syntax Tree API

Symbol API

Binding and Flow Analysis

APIsEmit API

Formatter

ColorizerOutlining

Navigate To

Object Browser

Completion List

Find All References

Rename

Quick Info

Signature Help

Extract M

ethod

Go To Definition

Edit and Continue

Parser Metadata Import

Binder IL Emitter

Symbols