dev340 microsoft visual c# under the covers: an in-depth look at c# 2.0 anders hejlsberg...
TRANSCRIPT
DEV340DEV340Microsoft Visual C# Microsoft Visual C# Under the Covers:Under the Covers:An In-Depth Look at C# 2.0An In-Depth Look at C# 2.0
Anders HejlsbergAnders HejlsbergDistinguished EngineerDistinguished EngineerMicrosoft CorporationMicrosoft Corporation
C# 2.0 EnhancementsC# 2.0 Enhancements
GenericsGenerics
Anonymous methodsAnonymous methods
Nullable typesNullable types
IteratorsIterators
Partial typesPartial types
and many more…and many more…
100% backwards compatible100% backwards compatible
public class Listpublic class List{{ private object[] elements;private object[] elements; private int count;private int count;
public void Add(object element) {public void Add(object element) { if (count == elements.Length) Resize(count * 2);if (count == elements.Length) Resize(count * 2); elements[count++] = element;elements[count++] = element; }}
public object this[int index] {public object this[int index] { get { return elements[index]; }get { return elements[index]; } set { elements[index] = value; }set { elements[index] = value; } }}
public int Count {public int Count { get { return count; }get { return count; } }}}}
GenericsGenericspublic class Listpublic class List<<TT>>{{ private private TT[] elements;[] elements; private int count;private int count;
public void Add(public void Add(TT element) { element) { if (count == elements.Length) Resize(count * 2);if (count == elements.Length) Resize(count * 2); elements[count++] = element;elements[count++] = element; }}
public public TT this[int index] { this[int index] { get { return elements[index]; }get { return elements[index]; } set { elements[index] = value; }set { elements[index] = value; } }}
public int Count {public int Count { get { return count; }get { return count; } }}}}
List intList = new List();List intList = new List();
intList.Add(1);intList.Add(1);intList.Add(2);intList.Add(2);intList.Add("Three");intList.Add("Three");
int i = (int)intList[0];int i = (int)intList[0];
List intList = new List();List intList = new List();
intList.Add(1);intList.Add(1); // Argument is boxed // Argument is boxedintList.Add(2);intList.Add(2); // Argument is boxed // Argument is boxedintList.Add("Three");intList.Add("Three"); // Should be an error // Should be an error
int i = (int)intList[0]; // Cast requiredint i = (int)intList[0]; // Cast required
ListList<<intint>> intList = new List intList = new List<<intint>>();();
intList.Add(1);intList.Add(1); // No boxing // No boxingintList.Add(2);intList.Add(2); // No boxing // No boxingintList.Add("Three");intList.Add("Three"); // Compile-time error // Compile-time error
int i = intList[0];int i = intList[0]; // No cast required // No cast required
GenericsGenerics
Why generics?Why generics?Type checking, no boxing, no downcastsType checking, no boxing, no downcasts
Increased sharing (typed collections)Increased sharing (typed collections)
How are C# generics implemented?How are C# generics implemented?Instantiated at run-time, not compile-timeInstantiated at run-time, not compile-time
Checked at declaration, not instantiationChecked at declaration, not instantiation
Work for both reference and value typesWork for both reference and value types
Exact run-time type informationExact run-time type information
GenericsGenerics
Type parameters can be applied toType parameters can be applied toClass, struct, interface, delegate typesClass, struct, interface, delegate types
class Dictionary<K,V> {...}class Dictionary<K,V> {...}
struct HashBucket<K,V> {...}struct HashBucket<K,V> {...}
interface IComparer<T> {...}interface IComparer<T> {...}
delegate R Function<A,R>(A arg);delegate R Function<A,R>(A arg);
Dictionary<string,Customer> customerLookupTable;Dictionary<string,Customer> customerLookupTable;
Dictionary<string,List<Order>> orderLookupTable;Dictionary<string,List<Order>> orderLookupTable;
Dictionary<string,int> wordCount;Dictionary<string,int> wordCount;
GenericsGenerics
Type parameters can be applied toType parameters can be applied toClass, struct, interface, delegate typesClass, struct, interface, delegate types
MethodsMethods
class Utilsclass Utils{{ public static T[] CreateArray<T>(T value, int size) {public static T[] CreateArray<T>(T value, int size) { T[] result = new T[size];T[] result = new T[size]; for (int i = 0; i < size; i++) result[i] = value;for (int i = 0; i < size; i++) result[i] = value; return result;return result; }}}} string[] names = Utils.CreateArray<string>("", 10);string[] names = Utils.CreateArray<string>("", 10);int[] numbers = Utils.CreateArray<int>(-1, 100);int[] numbers = Utils.CreateArray<int>(-1, 100);
string[] names = Utils.CreateArray("", 10);string[] names = Utils.CreateArray("", 10);int[] numbers = Utils.CreateArray(-1, 100);int[] numbers = Utils.CreateArray(-1, 100); TypeType
inference!inference!
GenericsGenerics
Type parameters can be applied toType parameters can be applied toClass, struct, interface, delegate typesClass, struct, interface, delegate types
MethodsMethods
Type parameters can have constraintsType parameters can have constraints
class Dictionary<K,V>class Dictionary<K,V>{{ public void Add(K key, V value) {public void Add(K key, V value) { ...... if (if (((IComparable)key).CompareTo(x) == 0((IComparable)key).CompareTo(x) == 0) {...}) {...} ...... }}}}
class Dictionary<K,V> class Dictionary<K,V> where K: IComparablewhere K: IComparable{{ public void Add(K key, V value) {public void Add(K key, V value) { ...... if (if (key.CompareTo(x) == 0key.CompareTo(x) == 0) {...}) {...} ...... }}}}
class Dictionary<K,V>: IDictionary<K,V>class Dictionary<K,V>: IDictionary<K,V> where K: IComparable<K>where K: IComparable<K> where V: IKeyProvider<K>, IPersistable, new()where V: IKeyProvider<K>, IPersistable, new(){{ public void Add(K key, V value) { public void Add(K key, V value) { ...... }}}}
GenericsGenerics
Zero or one primary constraintZero or one primary constraintActual class, Actual class, classclass, or , or structstruct
Zero or more secondary constraintsZero or more secondary constraintsInterface or type parameterInterface or type parameter
Zero or one constructor constraintZero or one constructor constraintnew()new()
class Link<T> where T: class {...}class Link<T> where T: class {...}
class Nullable<T> where T: struct {...}class Nullable<T> where T: struct {...}
class Relation<T,U> where T: class where U: T {...}class Relation<T,U> where T: class where U: T {...}
GenericsGenerics
default(T)default(T)
CastsCasts
Null checksNull checks
void Foo<T>() {void Foo<T>() { T x = null; // ErrorT x = null; // Error T y = default(T); // OkT y = default(T); // Ok}}
void Foo<T>(T x) {void Foo<T>(T x) { int i = (int)x; // Errorint i = (int)x; // Error int j = (int)(object)x; // Okint j = (int)(object)x; // Ok}}
void Foo<T>(T x) {void Foo<T>(T x) { if ((object)x == null) {...}if ((object)x == null) {...}}}
GenericsGenerics
Collection classesCollection classes
Collection interfacesCollection interfaces
Collection base classesCollection base classes
Utility classesUtility classes
ReflectionReflection
List<T>List<T>Dictionary<K,V>Dictionary<K,V>SortedDictionary<K,V>SortedDictionary<K,V>Stack<T>Stack<T>Queue<T>Queue<T>
IList<T>IList<T>IDictionary<K,V>IDictionary<K,V>ICollection<T>ICollection<T>IEnumerable<T>IEnumerable<T>IEnumerator<T>IEnumerator<T>IComparable<T>IComparable<T>IComparer<T>IComparer<T>
Collection<T>Collection<T>KeyedCollection<T>KeyedCollection<T>ReadOnlyCollection<T>ReadOnlyCollection<T>
Nullable<T>Nullable<T>EventHandler<T>EventHandler<T>Comparer<T>Comparer<T>
Anonymous MethodsAnonymous Methods
delegate bool Predicate<T>(T item);delegate bool Predicate<T>(T item);
public class List<T>public class List<T>{{ public List<T> FindAll(Predicate<T> filter) {public List<T> FindAll(Predicate<T> filter) { List<T> result = new List<T>();List<T> result = new List<T>(); foreach (T item in this) {foreach (T item in this) { if (filter(item)) result.Add(item);if (filter(item)) result.Add(item); }} return result;return result; }}}}
public class Bankpublic class Bank{{ List<Account> accounts;List<Account> accounts;
List<Account> GetOverdrawnAccounts() {List<Account> GetOverdrawnAccounts() { return accounts.FindAll(return accounts.FindAll( new Predicate<Account>(IsOverdrawn)new Predicate<Account>(IsOverdrawn) );); }}
static bool IsOwerdrawn(Account a) {static bool IsOwerdrawn(Account a) { return a.Balance < 0;return a.Balance < 0; }}}}
public class Bankpublic class Bank{{ List<Account> accounts;List<Account> accounts;
List<Account> GetOverdrawnAccounts() {List<Account> GetOverdrawnAccounts() { return accounts.FindAll(return accounts.FindAll( delegate(Account a) { return a.Balance < 0; }delegate(Account a) { return a.Balance < 0; } );); }}}}
Anonymous MethodsAnonymous Methods
Also known as Also known as functions functions
Code block in place of delegateCode block in place of delegate
Delegate type automatically inferredDelegate type automatically inferred
Code block may omit parameter listCode block may omit parameter list
button.Click += delegate { MessageBox.Show("Hello"); };button.Click += delegate { MessageBox.Show("Hello"); };
button.Click += delegate(object sender, EventArgs e) {button.Click += delegate(object sender, EventArgs e) { MessageBox.Show(((Button)sender).Text); MessageBox.Show(((Button)sender).Text);};};
Anonymous MethodsAnonymous Methods
Closures are supportedClosures are supported
public class Bankpublic class Bank{{ List<Account> accounts;List<Account> accounts;
List<Account> GetOverdrawnAccounts() {List<Account> GetOverdrawnAccounts() { return accounts.FindAll(return accounts.FindAll( delegate(Account a) { return a.Balance < 0; }delegate(Account a) { return a.Balance < 0; } );); }}}}
public class Bankpublic class Bank{{ List<Account> accounts;List<Account> accounts;
List<Account> GetOverdrawnAccounts() {List<Account> GetOverdrawnAccounts() { return accounts.FindAll(return accounts.FindAll( delegate(Account a) { return a.Balance < 0; }delegate(Account a) { return a.Balance < 0; } );); }}
List<Account> GetLargeAccounts(double minBal) {List<Account> GetLargeAccounts(double minBal) { return accounts.FindAll(return accounts.FindAll( delegate(Account a) { return a.Balance >= minBal; }delegate(Account a) { return a.Balance >= minBal; } );); }}}}
public class Bankpublic class Bank{{ List<Account> GetLargeAccounts(double minBal) {List<Account> GetLargeAccounts(double minBal) { Helper helper = new Helper();Helper helper = new Helper(); helper.minBal = minBal;helper.minBal = minBal; return accounts.FindAll(return accounts.FindAll(helper.Matcheshelper.Matches);); }}
internal class Helperinternal class Helper {{ internal double minBal;internal double minBal;
internal bool Matches(Account a) {internal bool Matches(Account a) { return a.Balance >= minBal;return a.Balance >= minBal; }} }}}}
Anonymous MethodsAnonymous Methods
Method group conversionsMethod group conversions
Delegate type inferred when possibleDelegate type inferred when possible
using System;using System;using System.Threading;using System.Threading;
class Programclass Program{{ static void Work() {...}static void Work() {...}
static void Main() {static void Main() { Thread t = new Thread(Thread t = new Thread(new ThreadStart(Work)new ThreadStart(Work));); t.Start();t.Start(); }}}}
using System;using System;using System.Threading;using System.Threading;
class Programclass Program{{ static void Work() {...}static void Work() {...}
static void Main() {static void Main() { Thread t = new Thread(Thread t = new Thread(WorkWork);); t.Start();t.Start(); }}}}
Generics PerformanceGenerics Performance
Nullable TypesNullable Types
System.Nullable<T>System.Nullable<T>Provides nullability for any value typeProvides nullability for any value type
Struct that combines a T and a boolStruct that combines a T and a bool
public struct Nullable<T> where T: structpublic struct Nullable<T> where T: struct{{ private T value;private T value; private bool hasValue;private bool hasValue;
public T Value { get { … } }public T Value { get { … } } public bool HasValue { get { … } }public bool HasValue { get { … } }}}
123123
intint
123123
Nullable<int>Nullable<int>
truetrue
??????
falsefalse
Non-nullNon-null NullNull
Nullable TypesNullable Types
T? syntaxT? syntax
null literalnull literal
ConversionsConversions
Lifted operatorsLifted operators
Null coalescingNull coalescing
int? x = 123;int? x = 123;double? y = 1.0;double? y = 1.0;
int? x = null;int? x = null;double? y = null;double? y = null;
int i = 123;int i = 123;int? x = i; // T int? x = i; // T T? implicit T? implicitint j = (int)x; // T? int j = (int)x; // T? T explicit T explicit
int? x = GetNullableInt();int? x = GetNullableInt();int? y = GetNullableInt();int? y = GetNullableInt();int? z = x + y;int? z = x + y;
int? x = GetNullableInt();int? x = GetNullableInt();int i = x ?? 0;int i = x ?? 0;
IteratorsIterators
foreach relies on “enumerator pattern”foreach relies on “enumerator pattern”GetEnumerator() methodGetEnumerator() method
foreach makes enumerating easyforeach makes enumerating easyBut enumerators are hard to write!But enumerators are hard to write!
foreach (object obj in list) {foreach (object obj in list) { DoSomething(obj);DoSomething(obj);}}
Enumerator e = list.GetEnumerator();Enumerator e = list.GetEnumerator();while (e.MoveNext()) {while (e.MoveNext()) { object obj = e.Current;object obj = e.Current; DoSomething(obj);DoSomething(obj);}}
IteratorsIterators
public class Listpublic class List{{ internal object[] elements;internal object[] elements; internal int count;internal int count;
public IEnumerator GetEnumerator() {public IEnumerator GetEnumerator() { return new ListEnumerator(this); return new ListEnumerator(this); }}}}
public class ListEnumerator : IEnumeratorpublic class ListEnumerator : IEnumerator{{ List list;List list; int index;int index;
internal ListEnumerator(List list) {internal ListEnumerator(List list) { this.list = list;this.list = list; index = -1;index = -1; }}
public bool MoveNext() {public bool MoveNext() { int i = index + 1;int i = index + 1; if (i >= list.count) return false;if (i >= list.count) return false; index = i;index = i; return true;return true; }}
public object Current {public object Current { get { return list.elements[index]; }get { return list.elements[index]; } }}}}
public class Listpublic class List{{ internal object[] elements;internal object[] elements; internal int count;internal int count;
public IEnumerator GetEnumerator() {public IEnumerator GetEnumerator() { for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) { yield return elements[i];yield return elements[i]; }} }}}}
public class Testpublic class Test{{ public IEnumerator GetEnumerator() {public IEnumerator GetEnumerator() { yield return "Hello";yield return "Hello"; yield return "World"; yield return "World"; }}}}
IteratorsIterators
Method that incrementally computes Method that incrementally computes and returns a sequence of valuesand returns a sequence of values
yield return and yield breakyield return and yield break
Must return IEnumerator or IEnumerableMust return IEnumerator or IEnumerable
public IEnumerator GetEnumerator() {public IEnumerator GetEnumerator() { return new __Enumerator(this);return new __Enumerator(this);}}
private class __Enumerator : IEnumeratorprivate class __Enumerator : IEnumerator{{ object current;object current; int state;int state;
public bool MoveNext() {public bool MoveNext() { switch (state) {switch (state) { case 0:case 0: current = "Hello";current = "Hello"; state = 1;state = 1; return true;return true; case 1:case 1: current = "World";current = "World"; state = 2;state = 2; return true;return true; default: default: return false;return false; }} }}
public object Current {public object Current { get { return current; }get { return current; } }}}}
public class List<T>public class List<T>{{ public IEnumerator<T> GetEnumerator() {public IEnumerator<T> GetEnumerator() { for (int i = 0; i < count; i++)for (int i = 0; i < count; i++) yield return elements[i];yield return elements[i]; }}
public IEnumerable<T> Descending() {public IEnumerable<T> Descending() { for (int i = count - 1; i >= 0; i--)for (int i = count - 1; i >= 0; i--) yield return elements[i];yield return elements[i]; }}
public IEnumerable<T> Subrange(int index, int n) {public IEnumerable<T> Subrange(int index, int n) { for (int i = 0; i < n; i++)for (int i = 0; i < n; i++) yield return elements[index + i];yield return elements[index + i]; }}}}
IteratorsIterators
List<Item> items = GetItemList();List<Item> items = GetItemList();foreach (Item x in items) {...}foreach (Item x in items) {...}foreach (Item x in items.Descending()) {...}foreach (Item x in items.Descending()) {...}foreach (Item x in Items.Subrange(10, 20)) {...}foreach (Item x in Items.Subrange(10, 20)) {...}
Partial TypesPartial Types
public public partialpartial class Customer class Customer{{ private int id;private int id; private string name;private string name; private string address;private string address; private List<Orders> orders;private List<Orders> orders;}}
public public partialpartial class Customer class Customer{{ public void SubmitOrder(Order order) {public void SubmitOrder(Order order) { orders.Add(order);orders.Add(order); }}
public bool HasOutstandingOrders() {public bool HasOutstandingOrders() { return orders.Count > 0;return orders.Count > 0; }}}}
public class Customerpublic class Customer{{ private int id;private int id; private string name;private string name; private string address;private string address; private List<Orders> orders;private List<Orders> orders;
public void SubmitOrder(Order order) {public void SubmitOrder(Order order) { orders.Add(order);orders.Add(order); }}
public bool HasOutstandingOrders() {public bool HasOutstandingOrders() { return orders.Count > 0;return orders.Count > 0; }}}}
Static ClassesStatic Classes
Only static membersOnly static members
Cannot be used as type of variable, Cannot be used as type of variable, parameter, field, property, …parameter, field, property, …
Examples include System.Console, Examples include System.Console, System.EnvironmentSystem.Environment
public public staticstatic class Math class Math{{ public static double Sin(double x) {...}public static double Sin(double x) {...} public static double Cos(double x) {...}public static double Cos(double x) {...} ......}}
Property AccessorsProperty Accessors
Different accessor accessibilityDifferent accessor accessibilityOne accessor can be restricted furtherOne accessor can be restricted further
Typically set {…} more restrictedTypically set {…} more restricted
public class Customerpublic class Customer{{ private string id;private string id;
public string CustomerId {public string CustomerId { get { return id; }get { return id; } internalinternal set { id = value; } set { id = value; } }}}}
External AliasesExternal Aliases
Enables use of identically named types Enables use of identically named types in different assembliesin different assemblies
namespace Stuffnamespace Stuff{{ public class Utilspublic class Utils {{ public static void F() {...}public static void F() {...} }}}}
namespace Stuffnamespace Stuff{{ public class Utilspublic class Utils {{ public static void F() {...}public static void F() {...} }}}}
foo.dllfoo.dll
bar.dllbar.dll
extern alias Foo;extern alias Foo;extern alias Bar;extern alias Bar;
class Programclass Program{{ static void Main() {static void Main() { Foo.Stuff.Utils.F();Foo.Stuff.Utils.F(); Bar.Stuff.Utils.F();Bar.Stuff.Utils.F(); }}}}
C:\>csc /r:Foo=foo.dll /r:Bar=bar.dll test.csC:\>csc /r:Foo=foo.dll /r:Bar=bar.dll test.cs
Namespace Alias QualifiersNamespace Alias Qualifiers
Enables more version resilient codeEnables more version resilient code
A::B looks up A only as aliasA::B looks up A only as alias
global::X looks up in global namespaceglobal::X looks up in global namespace
using IO = System.IO;using IO = System.IO;
class Programclass Program{{ static void Main() {static void Main() { IO::StreamIO::Stream s = new s = new IO::File.OpenReadIO::File.OpenRead("foo.txt");("foo.txt"); global::System.Console.WriteLineglobal::System.Console.WriteLine("Hello");("Hello"); }}}}
Inline Warning ControlInline Warning Control
#pragma warning#pragma warning
using System;using System;
class Programclass Program{{ [Obsolete][Obsolete] static void Foo() {}static void Foo() {}
static void Main() {static void Main() {#pragma warning disable 612#pragma warning disable 612 Foo();Foo();#pragma warning restore 612#pragma warning restore 612 }}}}
Fixed Size BuffersFixed Size Buffers
C style arrays in unsafe codeC style arrays in unsafe code
public struct OFSTRUCTpublic struct OFSTRUCT{{ public byte cBytes;public byte cBytes; public byte fFixedDisk;public byte fFixedDisk; public short nErrCode;public short nErrCode; private int Reserved;private int Reserved; public fixed char szPathName[128];public fixed char szPathName[128];}}
Want to know more?Want to know more?
WhiteboardWhiteboardCabana TalkCabana Talk
Cabana 6, MondayCabana 6, Monday5:00pm – 6:15pm5:00pm – 6:15pm
http://msdn.microsoft.com/vcsharp/languagehttp://msdn.microsoft.com/vcsharp/language
Book SigningBook SigningBook Store, TuesdayBook Store, Tuesday10:15am – 10:45am10:15am – 10:45am
Your FeedbackYour Feedbackis Important!is Important!
Please Fill Out a Survey forPlease Fill Out a Survey forThis Session on CommNetThis Session on CommNet
© 2005 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.