1Copyright Š 2012 Retalix |
|
Arnon Axelrod
C# IN DEPTH
2Copyright Š 2012 Retalix |
About me
3Copyright Š 2012 Retalix |
About you
Already familiar
with:?
 Reflection
 Generics
 Lambdas
 Linq
 dynamic
 async/await
4Copyright Š 2012 Retalix |
Anders Hejlsberg
5Copyright Š 2012 Retalix |
Today
• Background
• C# 1
• C# 2
• C# 3
• C# 4
• C# 5
(+Roslyn)
6Copyright Š 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
7Copyright Š 2012 Retalix |
Basic terms
8Copyright Š 2012 Retalix |
Class vs. Object
Class Objects
9Copyright Š 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 c
5 false 0x0000 … 3 4 ‘a’
0x1234 0x4567
x = new Class1()
y = new Class2();
x.c2 = y;
0x4567
Reference Object
10Copyright Š 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)
11Copyright Š 2012 Retalix |
Static variables
• Live for the entire lifespan of the process
• Fixed size
• Can reference objects on the heap
12Copyright Š 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
13Copyright Š 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
14Copyright Š 2012 Retalix |
Naming scopes
• Namespaces
• Private, public, internal, protected
• Nested types
15Copyright Š 2012 Retalix |
The .Net Framework
16Copyright Š 2012 Retalix |
The .NET Framework
Base Class Library
Common Language Specification
Common Language Runtime
ADO.NET: Data and XML
VB C++ C#
VisualStudio.NET
ASP.NET: Web Services
And Web Forms
JScript …
Windows
forms
17Copyright Š 2012 Retalix |
.Net
C# Compiler
CLR
JIT Compiler
MS
IL
18Copyright Š 2012 Retalix |
CLR
The JIT Compiler
void Main()
{
Foo();
Bar();
}
IL of Foo
void Foo()
{
...
Bar();
....
}
void Bar()
{
...
}
IL of Bar
Methods
table
Foo
Bar
…
JIT Compiler
JIT Compile(Foo)
JIT Compile(Bar)
Machine code
for Foo
Machine code
for Bar
19Copyright Š 2012 Retalix |
Garbage Collector
 Allocation in O(1)
 Automatic De-allocation
 Graph traversal
 Automatic De-fragmentation
 On a background thread
Next free
position
20Copyright Š 2012 Retalix |
CLR 4.5
CLR 4.0
CLR 2.0
CLR 1.0/1.1
.Net/C# evolution
C# 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
21Copyright Š 2012 Retalix |
The Compiler
22Copyright Š 2012 Retalix |
The Compiler pipeline
Lexical
Analyzer
Lexical
Analyzer
Lexical
Analyzer
Parser
Parser
Parser
Semantics
analyzer
/ Binder
IL
Emitter
23Copyright Š 2012 Retalix |
using System;
// comment
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Lexical Analyzer
KeywordIdentifierPunctuator
Comment
(ignore)Keyword KeywordIdentifier
Punctuator
Keyword Keyword KeywordIdentifierPunctuatorPunctuator
Punctuator
IdentifierPunctuatorIdentifierPunctuatorString literalPunctuatorPunctuator
Punctuator
Punctuator
24Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Compilation-
unit
Using-
namespace-
directive
Class-
declaration
25Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Class-
declaration
Class-
modifier
Identifier
Class-body
26Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Class-body
Class-
member-
declarations
27Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Class-
member-
declarations
Method-
declaration
28Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Method-
declaration
Method-
header
Method-
body
29Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Method-
body
Statements-
list
Statement
30Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
statement
Expression
Invocation-
expression
31Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Invocation-
expression
Primary-
expression
Argument-
list
32Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Primary-
expression
Member-
access
Primary-
expression
Identifier
33Copyright Š 2012 Retalix |
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello, World");
}
}
Parser
Primary-
expression
Simple-
name
identifier
34Copyright Š 2012 Retalix |
C# 1.0
35Copyright Š 2012 Retalix |
Static memory
Reflection
Methods Table
(MyClass)
Metadata
ToString()
Equals()
MyVirtualMethod()
…
MyClass
Metadata
Name
Derived types…
Fields
Methods
…
Instance 1 of
MyClass
Methods table
Instance
variables…
Instance 2 of
MyClass
Methods table
Instance
variables…
Instance 3 of
MyClass
Methods table
Instance
variables…
36Copyright Š 2012 Retalix |
Demo - Reflection
37Copyright Š 2012 Retalix |
Demo - Attributes
38Copyright Š 2012 Retalix |
Demo – Finalize and IDisposable
39Copyright Š 2012 Retalix |
Demo - IEnumerable
40Copyright Š 2012 Retalix |
Demo – Delegates & Events
41Copyright Š 2012 Retalix |
Demo - params
42Copyright Š 2012 Retalix |
Demo – Explicit & Implicit interface
implementations
43Copyright Š 2012 Retalix |
C# 2.0
44Copyright Š 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?!
}
45Copyright Š 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;
}
46Copyright Š 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
47Copyright Š 2012 Retalix |
Generics
Automatic 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
48Copyright Š 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
49Copyright Š 2012 Retalix |
Demo - Generics
50Copyright Š 2012 Retalix |
Generics - constraints
• struct / class
• Primary type and multiple interfaces
• new()
51Copyright Š 2012 Retalix |
Demo: Generics with constraints
52Copyright Š 2012 Retalix |
Nullable<T>
• int i = null; // syntax error
• int? is a syntactic sugar for System.Nullable<int>
• struct – no boxing/unboxing
53Copyright Š 2012 Retalix |
Demo – Nullable<T>
54Copyright Š 2012 Retalix |
Action, Func, Predicate
Delegates 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);
55Copyright Š 2012 Retalix |
Demo – Anonymous methods
56Copyright Š 2012 Retalix |
Demo – Iterator blocks
57Copyright Š 2012 Retalix |
Demo – Partial types
58Copyright Š 2012 Retalix |
C# 3
59Copyright Š 2012 Retalix |
Demo – type inference (var)
60Copyright Š 2012 Retalix |
Demo – initializer and auto-properties
61Copyright Š 2012 Retalix |
Demo – Anonymous types
62Copyright Š 2012 Retalix |
Demo – Lambda expressions
63Copyright Š 2012 Retalix |
Extension methods
Back 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
this
64Copyright Š 2012 Retalix |
Demo – “this”
65Copyright Š 2012 Retalix |
Extension methods - Motivation
class MyClass
{
//...
}
class SomeLibraryThatICannotTouch
{
MyClass CreateMyClass() { return new MyClass(); }
}
class MyDerivedClass : MyClass
{
public void AddedFunctionality() { … }
}
var myObject = SomeLibraryThatICannotTouch.CreateMyClass();
myObject.AddedFunctionality();
Compilation error!
66Copyright Š 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);
67Copyright Š 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);
68Copyright Š 2012 Retalix |
Extension methods
ThisIs().Some().Expression().MyExtensionMethod(3)
Is equivalent to:
ClassName.MyExtensionMethod(ThisIs().Some().Expression(), 3)
This is not an
expression – only a
naming scope
69Copyright Š 2012 Retalix |
Extension methods
Points 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)
70Copyright Š 2012 Retalix |
Demo – Extension methods
71Copyright Š 2012 Retalix |
Linq – Language
Integrated Queries
72Copyright Š 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);
73Copyright Š 2012 Retalix |
Query Expressions
• Language integrated query syntax
from 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 ]?
74Copyright Š 2012 Retalix |
from c in customers
where 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
75Copyright Š 2012 Retalix |
Demo – Linq to Object
76Copyright Š 2012 Retalix |
Expression Trees
77Copyright Š 2012 Retalix |
Expression Trees - motivation
• Linq to SQL / Entity Framework
from student in StudentsTable
where student.FirstName.Length == 4
orderby student.Grade descending
select new {student.LastName, student.Grade};
78Copyright Š 2012 Retalix |
Expression Trees
((16 + 5 x 4) / 9) + 17 x 3
79Copyright Š 2012 Retalix |
Demo – System.Linq.Expressions
(BatchFileCreator)
80Copyright Š 2012 Retalix |
Demo – Expression<Tdelegate>.Compile()
(DynamicMethodCreatorDemo)
81Copyright Š 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);
}
82Copyright Š 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);
83Copyright Š 2012 Retalix |
Demo – Entity Framework
84Copyright Š 2012 Retalix |
C# 4
85Copyright Š 2012 Retalix |
Optional and Named
Arguments
86Copyright Š 2012 Retalix |
Optional & Named Parameters
public 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
87Copyright Š 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 Parameters
Optional 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
88Copyright Š 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.
89Copyright Š 2012 Retalix |
Demo – Optional and named arguments
90Copyright Š 2012 Retalix |
Dynamic
91Copyright Š 2012 Retalix |
Python
Binder
Ruby
Binder
COM
Binder
JavaScript
Binder
Object
Binder
.NET Dynamic Programming
Dynamic Language Runtime (DLR)
Expression Trees Dynamic Dispatch Call Site Caching
IronPython IronRuby C# VB.NET Others…
92Copyright Š 2012 Retalix |
Dynamically Typed Objects
object 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
invocation
Dynamic
conversion
Syntax Error!
93Copyright Š 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 conversion
int num = x; // assignment conversion
94Copyright Š 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
95Copyright Š 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)
96Copyright Š 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);
}
97Copyright Š 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.
98Copyright Š 2012 Retalix |
Demo - Dynamic
99Copyright Š 2012 Retalix |
Co- & Contra- Variance
100Copyright Š 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){ ... }
101Copyright Š 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;
102Copyright Š 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 safely
co-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
103Copyright Š 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-variant
Output positions only
IEnumerable<string> strings = GetStrings();
IEnumerable<object> objects = strings;
Can be treated as
less derived
104Copyright Š 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-variant
Input positions only
Can be treated as
more derived
105Copyright Š 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
106Copyright Š 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
107Copyright Š 2012 Retalix |
Covariance and Contra-variance
Notes:
• 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>();
108Copyright Š 2012 Retalix |
Demo - Vairance
109Copyright Š 2012 Retalix |
C# 5
110Copyright Š 2012 Retalix |
ASYNC & AWAIT
111Copyright Š 2012 Retalix |
Terminology
• Multi-core
• Multi-threading
• Parallelism (e.g. Parallel.ForEach)
• Concurrency
– Can be single threaded!
CPU Bound
I/O Bound
async & await
112Copyright Š 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…)
113Copyright Š 2012 Retalix |
Synchronous vs. asynchronous
• var data = DownloadData(...);
• ProcessData(data);
var
114Copyright Š 2012 Retalix |
Synchronous vs. asynchronous
• var data = DownloadData(...);
• ProcessData(data);
var
115Copyright Š 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
116Copyright Š 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(…)
117Copyright Š 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
118Copyright Š 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
119Copyright Š 2012 Retalix |
async & await
public 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;
}
120Copyright Š 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()
121Copyright Š 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()
122Copyright Š 2012 Retalix |
Demo – async & await
123Copyright Š 2012 Retalix |
C# vNext
124Copyright Š 2012 Retalix |
Project “Roslyn” –
Compiler as a Service
125Copyright Š 2012 Retalix |
Class
Field
public Foo
private
string
X
The Roslyn project
CompilerCompilerSource
code
Source
code
Source
File
Source
code
Source
code
.NET
Assembly
Meta-programming Read-Eval-Print Loop
Language
Object Model
DSL Embedding
126Copyright Š 2012 Retalix |
Roslyn APIs
Language
Service
Compiler
APIs
Compiler
Pipeline
Syntax
Tree API
Symbol
API
Binding and
Flow Analysis
APIs
Emit
API
Formatter
Colorizer
Outlining
NavigateTo
ObjectBrowser
CompletionList
FindAll
References
Rename
QuickInfo
SignatureHelp
ExtractMethod
GoToDefinition
Editand
Continue
Parser
Metadata
Import
Binder
IL
Emitter
Symbols

C# in depth

  • 1.
    1Copyright Š 2012Retalix | | Arnon Axelrod C# IN DEPTH
  • 2.
    2Copyright Š 2012Retalix | About me
  • 3.
    3Copyright Š 2012Retalix | About you Already familiar with:?  Reflection  Generics  Lambdas  Linq  dynamic  async/await
  • 4.
    4Copyright Š 2012Retalix | Anders Hejlsberg
  • 5.
    5Copyright © 2012Retalix | Today • Background • C# 1 • C# 2 • C# 3 • C# 4 • C# 5 (+Roslyn)
  • 6.
    6Copyright Š 2012Retalix | 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
  • 7.
    7Copyright Š 2012Retalix | Basic terms
  • 8.
    8Copyright Š 2012Retalix | Class vs. Object Class Objects
  • 9.
    9Copyright © 2012Retalix | 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 c 5 false 0x0000 … 3 4 ‘a’ 0x1234 0x4567 x = new Class1() y = new Class2(); x.c2 = y; 0x4567 Reference Object
  • 10.
    10Copyright © 2012Retalix | 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)
  • 11.
    11Copyright © 2012Retalix | Static variables • Live for the entire lifespan of the process • Fixed size • Can reference objects on the heap
  • 12.
    12Copyright © 2012Retalix | 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
  • 13.
    13Copyright Š 2012Retalix | 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
  • 14.
    14Copyright © 2012Retalix | Naming scopes • Namespaces • Private, public, internal, protected • Nested types
  • 15.
    15Copyright Š 2012Retalix | The .Net Framework
  • 16.
    16Copyright © 2012Retalix | The .NET Framework Base Class Library Common Language Specification Common Language Runtime ADO.NET: Data and XML VB C++ C# VisualStudio.NET ASP.NET: Web Services And Web Forms JScript … Windows forms
  • 17.
    17Copyright Š 2012Retalix | .Net C# Compiler CLR JIT Compiler MS IL
  • 18.
    18Copyright © 2012Retalix | CLR The JIT Compiler void Main() { Foo(); Bar(); } IL of Foo void Foo() { ... Bar(); .... } void Bar() { ... } IL of Bar Methods table Foo Bar … JIT Compiler JIT Compile(Foo) JIT Compile(Bar) Machine code for Foo Machine code for Bar
  • 19.
    19Copyright Š 2012Retalix | Garbage Collector  Allocation in O(1)  Automatic De-allocation  Graph traversal  Automatic De-fragmentation  On a background thread Next free position
  • 20.
    20Copyright © 2012Retalix | CLR 4.5 CLR 4.0 CLR 2.0 CLR 1.0/1.1 .Net/C# evolution C# 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
  • 21.
    21Copyright Š 2012Retalix | The Compiler
  • 22.
    22Copyright Š 2012Retalix | The Compiler pipeline Lexical Analyzer Lexical Analyzer Lexical Analyzer Parser Parser Parser Semantics analyzer / Binder IL Emitter
  • 23.
    23Copyright Š 2012Retalix | using System; // comment public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Lexical Analyzer KeywordIdentifierPunctuator Comment (ignore)Keyword KeywordIdentifier Punctuator Keyword Keyword KeywordIdentifierPunctuatorPunctuator Punctuator IdentifierPunctuatorIdentifierPunctuatorString literalPunctuatorPunctuator Punctuator Punctuator
  • 24.
    24Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Compilation- unit Using- namespace- directive Class- declaration
  • 25.
    25Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Class- declaration Class- modifier Identifier Class-body
  • 26.
    26Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Class-body Class- member- declarations
  • 27.
    27Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Class- member- declarations Method- declaration
  • 28.
    28Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Method- declaration Method- header Method- body
  • 29.
    29Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Method- body Statements- list Statement
  • 30.
    30Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser statement Expression Invocation- expression
  • 31.
    31Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Invocation- expression Primary- expression Argument- list
  • 32.
    32Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Primary- expression Member- access Primary- expression Identifier
  • 33.
    33Copyright Š 2012Retalix | using System; public class Program { public static void Main() { Console.WriteLine("Hello, World"); } } Parser Primary- expression Simple- name identifier
  • 34.
    34Copyright Š 2012Retalix | C# 1.0
  • 35.
    35Copyright © 2012Retalix | Static memory Reflection Methods Table (MyClass) Metadata ToString() Equals() MyVirtualMethod() … MyClass Metadata Name Derived types… Fields Methods … Instance 1 of MyClass Methods table Instance variables… Instance 2 of MyClass Methods table Instance variables… Instance 3 of MyClass Methods table Instance variables…
  • 36.
    36Copyright Š 2012Retalix | Demo - Reflection
  • 37.
    37Copyright Š 2012Retalix | Demo - Attributes
  • 38.
    38Copyright © 2012Retalix | Demo – Finalize and IDisposable
  • 39.
    39Copyright Š 2012Retalix | Demo - IEnumerable
  • 40.
    40Copyright © 2012Retalix | Demo – Delegates & Events
  • 41.
    41Copyright Š 2012Retalix | Demo - params
  • 42.
    42Copyright © 2012Retalix | Demo – Explicit & Implicit interface implementations
  • 43.
    43Copyright Š 2012Retalix | C# 2.0
  • 44.
    44Copyright © 2012Retalix | 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?! }
  • 45.
    45Copyright © 2012Retalix | 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; }
  • 46.
    46Copyright © 2012Retalix | 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
  • 47.
    47Copyright © 2012Retalix | Generics Automatic 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
  • 48.
    48Copyright © 2012Retalix | 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
  • 49.
    49Copyright Š 2012Retalix | Demo - Generics
  • 50.
    50Copyright © 2012Retalix | Generics - constraints • struct / class • Primary type and multiple interfaces • new()
  • 51.
    51Copyright Š 2012Retalix | Demo: Generics with constraints
  • 52.
    52Copyright © 2012Retalix | Nullable<T> • int i = null; // syntax error • int? is a syntactic sugar for System.Nullable<int> • struct – no boxing/unboxing
  • 53.
    53Copyright © 2012Retalix | Demo – Nullable<T>
  • 54.
    54Copyright © 2012Retalix | Action, Func, Predicate Delegates 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);
  • 55.
    55Copyright © 2012Retalix | Demo – Anonymous methods
  • 56.
    56Copyright © 2012Retalix | Demo – Iterator blocks
  • 57.
    57Copyright © 2012Retalix | Demo – Partial types
  • 58.
    58Copyright Š 2012Retalix | C# 3
  • 59.
    59Copyright © 2012Retalix | Demo – type inference (var)
  • 60.
    60Copyright © 2012Retalix | Demo – initializer and auto-properties
  • 61.
    61Copyright © 2012Retalix | Demo – Anonymous types
  • 62.
    62Copyright © 2012Retalix | Demo – Lambda expressions
  • 63.
    63Copyright © 2012Retalix | Extension methods Back 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 this
  • 64.
    64Copyright © 2012Retalix | Demo – “this”
  • 65.
    65Copyright © 2012Retalix | Extension methods - Motivation class MyClass { //... } class SomeLibraryThatICannotTouch { MyClass CreateMyClass() { return new MyClass(); } } class MyDerivedClass : MyClass { public void AddedFunctionality() { … } } var myObject = SomeLibraryThatICannotTouch.CreateMyClass(); myObject.AddedFunctionality(); Compilation error!
  • 66.
    66Copyright © 2012Retalix | Extension methods public static MyExtensionClass { public static void MyExtensionMethod(MyClass myObject, int i) { // Do something… } } var myObject = SomeLibraryThatICannotTouch.CreateMyClass(); MyExtensionClass.MyExtensionMethod(myObject, 3);
  • 67.
    67Copyright © 2012Retalix | Extension methods public static MyExtensionClass { public static void MyExtensionMethod(this MyClass myObject, int i) { // Do something… } } var myObject = SomeLibraryThatICannotTouch.CreateMyClass(); myObject.MyExtensionMethod(3);
  • 68.
    68Copyright © 2012Retalix | Extension methods ThisIs().Some().Expression().MyExtensionMethod(3) Is equivalent to: ClassName.MyExtensionMethod(ThisIs().Some().Expression(), 3) This is not an expression – only a naming scope
  • 69.
    69Copyright © 2012Retalix | Extension methods Points 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)
  • 70.
    70Copyright © 2012Retalix | Demo – Extension methods
  • 71.
    71Copyright © 2012Retalix | Linq – Language Integrated Queries
  • 72.
    72Copyright Š 2012Retalix | 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);
  • 73.
    73Copyright © 2012Retalix | Query Expressions • Language integrated query syntax from 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 ]?
  • 74.
    74Copyright © 2012Retalix | from c in customers where 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
  • 75.
    75Copyright © 2012Retalix | Demo – Linq to Object
  • 76.
    76Copyright Š 2012Retalix | Expression Trees
  • 77.
    77Copyright © 2012Retalix | Expression Trees - motivation • Linq to SQL / Entity Framework from student in StudentsTable where student.FirstName.Length == 4 orderby student.Grade descending select new {student.LastName, student.Grade};
  • 78.
    78Copyright Š 2012Retalix | Expression Trees ((16 + 5 x 4) / 9) + 17 x 3
  • 79.
    79Copyright © 2012Retalix | Demo – System.Linq.Expressions (BatchFileCreator)
  • 80.
    80Copyright © 2012Retalix | Demo – Expression<Tdelegate>.Compile() (DynamicMethodCreatorDemo)
  • 81.
    81Copyright Š 2012Retalix | 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); }
  • 82.
    82Copyright Š 2012Retalix | 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);
  • 83.
    83Copyright © 2012Retalix | Demo – Entity Framework
  • 84.
    84Copyright Š 2012Retalix | C# 4
  • 85.
    85Copyright Š 2012Retalix | Optional and Named Arguments
  • 86.
    86Copyright Š 2012Retalix | Optional & Named Parameters public 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
  • 87.
    87Copyright Š 2012Retalix | 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 Parameters Optional 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
  • 88.
    88Copyright © 2012Retalix | 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.
  • 89.
    89Copyright © 2012Retalix | Demo – Optional and named arguments
  • 90.
    90Copyright Š 2012Retalix | Dynamic
  • 91.
    91Copyright © 2012Retalix | Python Binder Ruby Binder COM Binder JavaScript Binder Object Binder .NET Dynamic Programming Dynamic Language Runtime (DLR) Expression Trees Dynamic Dispatch Call Site Caching IronPython IronRuby C# VB.NET Others…
  • 92.
    92Copyright Š 2012Retalix | Dynamically Typed Objects object 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 invocation Dynamic conversion Syntax Error!
  • 93.
    93Copyright © 2012Retalix | 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 conversion int num = x; // assignment conversion
  • 94.
    94Copyright © 2012Retalix | 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
  • 95.
    95Copyright © 2012Retalix | 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)
  • 96.
    96Copyright Š 2012Retalix | 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); }
  • 97.
    97Copyright © 2012Retalix | 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.
  • 98.
    98Copyright Š 2012Retalix | Demo - Dynamic
  • 99.
    99Copyright Š 2012Retalix | Co- & Contra- Variance
  • 100.
    100Copyright © 2012Retalix | 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){ ... }
  • 101.
    101Copyright © 2012Retalix | 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;
  • 102.
    102Copyright © 2012Retalix | 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 safely co-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
  • 103.
    103Copyright Š 2012Retalix | 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-variant Output positions only IEnumerable<string> strings = GetStrings(); IEnumerable<object> objects = strings; Can be treated as less derived
  • 104.
    104Copyright Š 2012Retalix | 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-variant Input positions only Can be treated as more derived
  • 105.
    105Copyright © 2012Retalix | 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
  • 106.
    106Copyright © 2012Retalix | 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
  • 107.
    107Copyright © 2012Retalix | Covariance and Contra-variance Notes: • 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>();
  • 108.
    108Copyright Š 2012Retalix | Demo - Vairance
  • 109.
    109Copyright Š 2012Retalix | C# 5
  • 110.
    110Copyright Š 2012Retalix | ASYNC & AWAIT
  • 111.
    111Copyright © 2012Retalix | Terminology • Multi-core • Multi-threading • Parallelism (e.g. Parallel.ForEach) • Concurrency – Can be single threaded! CPU Bound I/O Bound async & await
  • 112.
    112Copyright © 2012Retalix | 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…)
  • 113.
    113Copyright © 2012Retalix | Synchronous vs. asynchronous • var data = DownloadData(...); • ProcessData(data); var
  • 114.
    114Copyright © 2012Retalix | Synchronous vs. asynchronous • var data = DownloadData(...); • ProcessData(data); var
  • 115.
    115Copyright © 2012Retalix | 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
  • 116.
    116Copyright © 2012Retalix | The Task/Task<Tresult> classes • Abstraction for a unit of work • Task.Factory.StartNew / Task.Run • Task.Wait • TResult Task.Result • Task.ContinueWith(…)
  • 117.
    117Copyright © 2012Retalix | 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
  • 118.
    118Copyright © 2012Retalix | 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
  • 119.
    119Copyright Š 2012Retalix | async & await public 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; }
  • 120.
    120Copyright © 2012Retalix | 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()
  • 121.
    121Copyright © 2012Retalix | 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()
  • 122.
    122Copyright © 2012Retalix | Demo – async & await
  • 123.
    123Copyright Š 2012Retalix | C# vNext
  • 124.
    124Copyright © 2012Retalix | Project “Roslyn” – Compiler as a Service
  • 125.
    125Copyright Š 2012Retalix | Class Field public Foo private string X The Roslyn project CompilerCompilerSource code Source code Source File Source code Source code .NET Assembly Meta-programming Read-Eval-Print Loop Language Object Model DSL Embedding
  • 126.
    126Copyright Š 2012Retalix | Roslyn APIs Language Service Compiler APIs Compiler Pipeline Syntax Tree API Symbol API Binding and Flow Analysis APIs Emit API Formatter Colorizer Outlining NavigateTo ObjectBrowser CompletionList FindAll References Rename QuickInfo SignatureHelp ExtractMethod GoToDefinition Editand Continue Parser Metadata Import Binder IL Emitter Symbols