1 / 31

DEV321 Visual C# 2005: Language Enhancements

DEV321 Visual C# 2005: Language Enhancements. Anders Hejlsberg Distinguished Engineer Microsoft Corporation. C# Language Enhancements. Generics Anonymous methods Nullable types Iterators Partial types and many more… 100% backwards compatible. Generics. public class List {

mairi
Télécharger la présentation

DEV321 Visual C# 2005: Language Enhancements

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. DEV321 Visual C# 2005:Language Enhancements Anders Hejlsberg Distinguished Engineer Microsoft Corporation

  2. C# Language Enhancements • Generics • Anonymous methods • Nullable types • Iterators • Partial types • and many more… • 100% backwards compatible

  3. Generics public class List { private object[] elements; private int count; public void Add(object element) { if (count == elements.Length) Resize(count * 2); elements[count++] = element; } public object this[int index] { get { return elements[index]; } set { elements[index] = value; } } public int Count { get { return count; } } } public class List<T> { private T[] elements; private int count; public void Add(T element) { if (count == elements.Length) Resize(count * 2); elements[count++] = element; } public T this[int index] { get { return elements[index]; } set { elements[index] = value; } } public int 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<int> intList = new List<int>(); intList.Add(1); // No boxing intList.Add(2); // No boxing intList.Add("Three"); // Compile-time error int i = intList[0]; // No cast required

  4. Generics • Why generics? • Type checking, no boxing, no downcasts • Reduced code bloat (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 • Complete run-time type information

  5. Generics • Type parameters can be applied to • Class, struct, interface, delegate types class Dictionary<K,V> {...} struct HashBucket<K,V> {...} interface IComparer<T> {...} delegate R Function<A,R>(A arg); Dictionary<string,Customer> customerLookupTable; Dictionary<string,List<Order>> orderLookupTable; Dictionary<string,int> wordCount;

  6. Generics • Type parameters can be applied to • Class, struct, interface, delegate types • Methods class Utils{ public static T[] CreateArray<T>(int size) { return new T[size]; } public static void SortArray<T>(T[] array) { ... } } string[] names = Utils.CreateArray<string>(10); names[0] = "Jones"; ... Utils.SortArray(names);

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

  8. 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<T> where T: class {...} class Nullable<T> where T: struct {...} class Relation<T,U> where T: class where U: T {...}

  9. Generics List<T> Dictionary<K,V> SortedDictionary<K,V> Stack<T> Queue<T> • Collection classes • Collection interfaces • Collection base classes • Utility classes • Reflection 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>

  10. Anonymous Methods class MyForm : Form { ListBox listBox; TextBox textBox; Button addButton; public MyForm() { listBox = new ListBox(...); textBox = new TextBox(...); addButton = new Button(...); addButton.Click += new EventHandler(AddClick); } void AddClick(object sender, EventArgs e) { listBox.Items.Add(textBox.Text); } } class MyForm : Form { ListBox listBox; TextBox textBox; Button addButton; public MyForm() { listBox = new ListBox(...); textBox = new TextBox(...); addButton = new Button(...); addButton.Click += delegate { listBox.Items.Add(textBox.Text); }; } }

  11. Anonymous Methods • Allows code block in place of delegate • Delegate type automatically inferred • Code block can be parameterless • Or code block can have parameters • In either case, return types must match button.Click += delegate { MessageBox.Show("Hello"); }; button.Click += delegate(object sender, EventArgs e) { MessageBox.Show(((Button)sender).Text);};

  12. Anonymous Methods • Code block can access local variables public class Bank { List<Account> GetLargeAccounts(double minBalance) { Helper helper = new Helper(); helper.minBalance = minBalance; return accounts.FindAll(helper.Matches); } internal class Helper { internal double minBalance; internal bool Matches(Account a) { return a.Balance >= minBalance; } }} public class Bank { List<Account> accounts; List<Account> GetOverdrawnAccounts() { return accounts.FindAll(delegate(Account a) { return a.Balance < 0; }); } List<Account> GetLargeAccounts(double minBalance) { return accounts.FindAll(delegate(Account a) { return a.Balance >= minBalance; }); } } delegate bool Predicate<T>(T item); public class List<T> { public List<T> FindAll(Predicate<T> filter) { List<T> result = new List<T>(); foreach (T item in this) { if (filter(item)) result.Add(item); } return result; } }

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

  14. Generics Performance

  15. Nullable Types • System.Nullable<T> • Provides nullability for any value type • Struct that combines a T and a bool public struct Nullable<T> where T: struct { public Nullable(T value) {...} public T Value { get {...} } public bool HasValue { get {...} } ... } Nullable<int> x = new Nullable<int>(123); ... if (x.HasValue) Console.WriteLine(x.Value);

  16. Nullable Types • T? same as System.Nullable<T> • null literal conversions • Nullable conversions int? x = 123; double? y = 1.25; int? x = null; double? y = null; int i = 123; int? x = i; // int --> int?double? y = x; // int? --> double? int? z = (int?)y; // double? --> int? int j = (int)z; // int? --> int

  17. Nullable Types • Lifted conversions and operators • Comparison operators • Null coalescing operator int? x = GetNullableInt(); int? y = GetNullableInt(); int? z = x + y; int? x = GetNullableInt(); if (x == null) Console.WriteLine("x is null"); if (x < 0) Console.WriteLine("x less than zero"); int? x = GetNullableInt(); int i = x ?? 0;

  18. 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); } Enumerator e = list.GetEnumerator(); while (e.MoveNext()) { object obj = e.Current; DoSomething(obj); }

  19. Iterators public class ListEnumerator : IEnumerator { List list; int index; internal ListEnumerator(List list) { this.list = list; index = -1; } public bool MoveNext() { int i = index + 1; if (i >= list.count) return false; index = i; return true; } public object Current { get { return list.elements[index]; } } } public class List { internal object[] elements; internal int count; public IEnumerator GetEnumerator() { return new ListEnumerator(this); } } public class List { internal object[] elements; internal int count; public IEnumerator GetEnumerator() { for (int i = 0; i < count; i++) { yield return elements[i]; } } }

  20. public IEnumerator GetEnumerator() { return new __Enumerator(this); } private class __Enumerator : IEnumerator{ object current; int state; public bool MoveNext() { switch (state) { case 0: current = "Hello"; state = 1; return true; case 1: current = "World"; state = 2; return true; default: return false; } } public object Current { get { return current; } } } Iterators • Method that incrementally computes and returns a sequence of values • yield return and yield break • Must return IEnumerator or IEnumerable public class Test { public IEnumerator GetEnumerator() { yield return "Hello"; yield return "World"; } }

  21. Iterators public class List<T> { public IEnumerator<T> GetEnumerator() { for (int i = 0; i < count; i++) yield return elements[i]; } public IEnumerable<T> Descending() { for (int i = count - 1; i >= 0; i--) yield return elements[i]; } public IEnumerable<T> Subrange(int index, int n) { for (int i = 0; i < n; i++) yield return elements[index + i]; } } List<Item> items = GetItemList(); foreach (Item x in items) {...} foreach (Item x in items.Descending()) {...} foreach (Item x in Items.Subrange(10, 20)) {...}

  22. Partial Types public partial class Customer { private int id; private string name; private string address; private List<Orders> orders; } public class Customer { private int id; private string name; private string address; private List<Orders> orders; public void SubmitOrder(Order order) { orders.Add(order); } public bool HasOutstandingOrders() { return orders.Count > 0; } } public partial class Customer { public void SubmitOrder(Order order) { orders.Add(order); } public bool HasOutstandingOrders() { return orders.Count > 0; } }

  23. 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 Cos(double x) {...} ... }

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

  25. External Aliases • Enables use of identically named types in different assemblies namespace Stuff { public class Utils { public static void F() {...} } } foo.dll extern alias Foo; extern alias Bar; class Program { static void Main() { Foo.Stuff.Utils.F(); Bar.Stuff.Utils.F(); } } namespace Stuff { public class Utils { public static void F() {...} } } bar.dll C:\>csc /r:Foo=foo.dll /r:Bar=bar.dll test.cs

  26. 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() { IO::Stream s = new IO::File.OpenRead("foo.txt"); global::System.Console.WriteLine("Hello"); } }

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

  28. Fixed Size Buffers • C style arrays in unsafe code public struct OFSTRUCT { public byte cBytes; public byte fFixedDisk; public short nErrCode; private int Reserved; public fixed char szPathName[128]; }

  29. Want to know more? http://msdn.microsoft.com/vcsharp/language Book Signing Wednesday 12:30 – 1:30 Cabana Session Wednesday 2:00 – 3:15 Cabana 5

  30. Please fill out a session evaluation on CommNet Q1: Overall satisfaction with the session Q2: Usefulness of the information Q3: Presenter’s knowledge of the subject Q4: Presenter’s presentation skills Q5: Effectiveness of the presentation

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

More Related