Presentation is loading. Please wait.

Presentation is loading. Please wait.

DEV340 Microsoft Visual C# Under the Covers: An In-Depth Look at C# 2.0 Anders Hejlsberg Distinguished Engineer Microsoft Corporation.

Similar presentations


Presentation on theme: "DEV340 Microsoft Visual C# Under the Covers: An In-Depth Look at C# 2.0 Anders Hejlsberg Distinguished Engineer Microsoft Corporation."— Presentation transcript:

1 DEV340 Microsoft Visual C# Under the Covers: An In-Depth Look at C# 2.0 Anders Hejlsberg Distinguished Engineer Microsoft Corporation

2

3 C# 2.0 Enhancements Generics Anonymous methods Nullable types Iterators Partial types and many more… 100% backwards compatible

4 public 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; } }} Generics public class List public class List { private T[] elements; private T[] elements; private int count; private int count; public void Add(T element) { public void Add(T element) { if (count == elements.Length) Resize(count * 2); if (count == elements.Length) Resize(count * 2); elements[count++] = element; elements[count++] = element; } public T this[int index] { public T 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(); intList.Add(1);intList.Add(2);intList.Add("Three"); int i = (int)intList[0]; List intList = new List(); intList.Add(1); // Argument is boxed intList.Add(2); // Argument is boxed intList.Add("Three"); // Should be an error int i = (int)intList[0]; // Cast required List intList = new List (); intList.Add(1); // No boxing intList.Add(2); // No boxing intList.Add("Three"); // Compile-time error int i = intList[0]; // No cast required

5 Generics Why generics? Type checking, no boxing, no downcasts Increased sharing (typed collections) How are C# generics implemented? Instantiated at run-time, not compile-time Checked at declaration, not instantiation Work for both reference and value types Exact run-time type information

6 Generics Type parameters can be applied to Class, struct, interface, delegate types class Dictionary {...} struct HashBucket {...} interface IComparer {...} delegate R Function (A arg); Dictionary customerLookupTable; Dictionary > orderLookupTable; Dictionary wordCount;

7 Generics Type parameters can be applied to Class, struct, interface, delegate types Methods class Utils { public static T[] CreateArray (T value, int size) { public static T[] CreateArray (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 ("", 10); int[] numbers = Utils.CreateArray (-1, 100); string[] names = Utils.CreateArray("", 10); int[] numbers = Utils.CreateArray(-1, 100); Type inference!

8 Generics Type parameters can be applied to Class, struct, interface, delegate types Methods Type parameters can have constraints class Dictionary class Dictionary { public void Add(K key, V value) { public void Add(K key, V value) {...... if (((IComparable)key).CompareTo(x) == 0) {...} if (((IComparable)key).CompareTo(x) == 0) {...}...... }} class Dictionary where K: IComparable { public void Add(K key, V value) { public void Add(K key, V value) {...... if (key.CompareTo(x) == 0) {...} if (key.CompareTo(x) == 0) {...}...... }} class Dictionary : IDictionary class Dictionary : IDictionary where K: IComparable where K: IComparable where V: IKeyProvider, IPersistable, new() where V: IKeyProvider, IPersistable, new() { public void Add(K key, V value) {...... }}

9 Generics Zero or one primary constraint Actual class, class, or struct Zero or more secondary constraints Interface or type parameter Zero or one constructor constraint new() class Link where T: class {...} class Nullable where T: struct {...} class Relation where T: class where U: T {...}

10 Generics default(T)Casts Null checks void Foo () { T x = null; // Error T x = null; // Error T y = default(T); // Ok T y = default(T); // Ok} void Foo (T x) { int i = (int)x; // Error int i = (int)x; // Error int j = (int)(object)x; // Ok int j = (int)(object)x; // Ok} void Foo (T x) { if ((object)x == null) {...} if ((object)x == null) {...}}

11 Generics Collection classes Collection interfaces Collection base classes Utility classes Reflection List<T>Dictionary<K,V>SortedDictionary<K,V>Stack<T>Queue<T> IList<T>IDictionary<K,V>ICollection<T>IEnumerable<T>IEnumerator<T>IComparable<T>IComparer<T> Collection<T>KeyedCollection<T>ReadOnlyCollection<T> Nullable<T>EventHandler<T>Comparer<T>

12 Anonymous Methods delegate bool Predicate (T item); public class List public class List { public List FindAll(Predicate filter) { public List FindAll(Predicate filter) { List result = new List (); List result = new List (); 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 Bank { List accounts; List accounts; List GetOverdrawnAccounts() { List GetOverdrawnAccounts() { return accounts.FindAll( return accounts.FindAll( new Predicate (IsOverdrawn) new Predicate (IsOverdrawn) ); ); } static bool IsOwerdrawn(Account a) { static bool IsOwerdrawn(Account a) { return a.Balance < 0; return a.Balance < 0; }} public class Bank { List accounts; List accounts; List GetOverdrawnAccounts() { List GetOverdrawnAccounts() { return accounts.FindAll( return accounts.FindAll( delegate(Account a) { return a.Balance < 0; } delegate(Account a) { return a.Balance < 0; } ); ); }}

13 Anonymous Methods Also known as functions Code block in place of delegate Delegate type automatically inferred Code block may omit parameter list button.Click += delegate { MessageBox.Show("Hello"); }; button.Click += delegate(object sender, EventArgs e) { MessageBox.Show(((Button)sender).Text); };

14 Anonymous Methods Closures are supported public class Bank { List accounts; List accounts; List GetOverdrawnAccounts() { List GetOverdrawnAccounts() { return accounts.FindAll( return accounts.FindAll( delegate(Account a) { return a.Balance < 0; } delegate(Account a) { return a.Balance < 0; } ); ); }} public class Bank { List accounts; List accounts; List GetOverdrawnAccounts() { List GetOverdrawnAccounts() { return accounts.FindAll( return accounts.FindAll( delegate(Account a) { return a.Balance < 0; } delegate(Account a) { return a.Balance < 0; } ); ); } List GetLargeAccounts(double minBal) { List 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 Bank { List GetLargeAccounts(double minBal) { List GetLargeAccounts(double minBal) { Helper helper = new Helper(); Helper helper = new Helper(); helper.minBal = minBal; helper.minBal = minBal; return accounts.FindAll(helper.Matches); return accounts.FindAll(helper.Matches); } internal class Helper internal 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; } } } } }

15 Anonymous Methods Method group conversions Delegate type inferred when possible using System; using System.Threading; class Program { static void Work() {...} static void Work() {...} static void Main() { static void Main() { Thread t = new Thread(new ThreadStart(Work)); Thread t = new Thread(new ThreadStart(Work)); t.Start(); t.Start(); }} using System; using System.Threading; class Program { static void Work() {...} static void Work() {...} static void Main() { static void Main() { Thread t = new Thread(Work); Thread t = new Thread(Work); t.Start(); t.Start(); }}

16 Generics Performance

17 Nullable Types System.Nullable<T> Provides nullability for any value type Struct that combines a T and a bool public struct Nullable 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 { … } }} 123 int 123 Nullable<int> true ??? false Non-nullNull

18 Nullable Types T? syntax null literal Conversions Lifted operators Null coalescing int? x = 123; double? y = 1.0; int? x = null; double? y = null; int i = 123; int? x = i; // T  T? implicit int j = (int)x; // T?  T explicit int? x = GetNullableInt(); int? y = GetNullableInt(); int? z = x + y; int? x = GetNullableInt(); int i = x ?? 0;

19 Iterators foreach relies on “enumerator pattern” GetEnumerator() method foreach makes enumerating easy But enumerators are hard to write! foreach (object obj in list) { DoSomething(obj); DoSomething(obj);} Enumerator e = list.GetEnumerator(); while (e.MoveNext()) { object obj = e.Current; object obj = e.Current; DoSomething(obj); DoSomething(obj);}

20 Iterators public class List { internal object[] elements; internal object[] elements; internal int count; internal int count; public IEnumerator GetEnumerator() { return new ListEnumerator(this); public IEnumerator GetEnumerator() { return new ListEnumerator(this); }} public 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 List { internal object[] elements; internal object[] elements; internal int count; internal int count; public IEnumerator GetEnumerator() { for (int i = 0; i < count; i++) { public IEnumerator GetEnumerator() { for (int i = 0; i < count; i++) { yield return elements[i]; yield return elements[i]; } }}

21 public class Test { public IEnumerator GetEnumerator() { public IEnumerator GetEnumerator() { yield return "Hello"; yield return "World"; yield return "Hello"; yield return "World"; }} Iterators Method that incrementally computes and returns a sequence of values yield return and yield break Must return IEnumerator or IEnumerable public IEnumerator GetEnumerator() { return new __Enumerator(this); return new __Enumerator(this);} private 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; default: return true; default: return false; return false; } } public object Current { public object Current { get { return current; } get { return current; } }}

22 public class List public class List { 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 IEnumerable Descending() { public IEnumerable 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 Subrange(int index, int n) { public IEnumerable 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]; }} Iterators List items = GetItemList(); foreach (Item x in items) {...} foreach (Item x in items.Descending()) {...} foreach (Item x in Items.Subrange(10, 20)) {...}

23 Partial Types public partial class Customer { private int id; private int id; private string name; private string name; private string address; private string address; private List orders; private List orders;} public partial 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 Customer { private int id; private int id; private string name; private string name; private string address; private string address; private List orders; private List 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; }}

24 Static Classes Only static members Cannot be used as type of variable, parameter, field, property, … Examples include System.Console, System.Environment public static 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) {...}......}

25 Property Accessors Different accessor accessibility One accessor can be restricted further Typically set {…} more restricted public class Customer { private string id; private string id; public string CustomerId { public string CustomerId { get { return id; } get { return id; } internal set { id = value; } internal set { id = value; } }}

26 External Aliases Enables use of identically named types in different assemblies namespace Stuff { public class Utils public class Utils { public static void F() {...} public static void F() {...} }} namespace Stuff { public class Utils public class Utils { public static void F() {...} public static void F() {...} }} foo.dll bar.dll extern alias Foo; extern alias Bar; class 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.cs

27 Namespace Alias Qualifiers Enables more version resilient code A::B looks up A only as alias global::X looks up in global namespace using IO = System.IO; class Program { static void Main() { static void Main() { IO::Stream s = new IO::File.OpenRead("foo.txt"); IO::Stream s = new IO::File.OpenRead("foo.txt"); global::System.Console.WriteLine("Hello"); global::System.Console.WriteLine("Hello"); }}

28 Inline Warning Control #pragma warning using System; class Program { [Obsolete] [Obsolete] static void Foo() {} static void Foo() {} static void Main() { static void Main() { #pragma warning disable 612 Foo(); Foo(); #pragma warning restore 612 }}

29 Fixed Size Buffers C style arrays in unsafe code public 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];}

30 Want to know more? Whiteboard Cabana Talk Cabana 6, Monday 5:00pm – 6:15pm http://msdn.microsoft.com/vcsharp/language Book Signing Book Store, Tuesday 10:15am – 10:45am

31 Your Feedback is Important! Please Fill Out a Survey for This Session on CommNet

32 © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.


Download ppt "DEV340 Microsoft Visual C# Under the Covers: An In-Depth Look at C# 2.0 Anders Hejlsberg Distinguished Engineer Microsoft Corporation."

Similar presentations


Ads by Google