Visual C# 2005: IDE Enhancements Dan Fernandez C# Product Manager [email protected] http://blogs.msdn.com/danielfe/ Agenda • Generics • Anonymous methods • Nullable types • Iterators • Partial types • and many more… • 100%
Download ReportTranscript Visual C# 2005: IDE Enhancements Dan Fernandez C# Product Manager [email protected] http://blogs.msdn.com/danielfe/ Agenda • Generics • Anonymous methods • Nullable types • Iterators • Partial types • and many more… • 100%
Visual C# 2005: IDE Enhancements Dan Fernandez C# Product Manager [email protected] http://blogs.msdn.com/danielfe/ Agenda • Generics • Anonymous methods • Nullable types • Iterators • Partial types • and many more… • 100% backwards compatible 2 Generics • What are they? – Code that allows you to pass the data type as a parameter. – Rather then explicitly declaring the data type (int, string) when writing code, you use a generic data type instead • Benefits – Code reusability – Type checking, no boxing, no downcasts – Reduced code bloat (typed collections) 3 Generic Basics • T can be used for any numerical type public struct Point { public long X; public long Y; } public struct Point<T> { public T X; public T Y; } public struct Point { public int X; public int Y; } Point<int> point; point.X = 10; point.Y = 20; public struct Point { public float X; public float Y; } Point<float> point; point.X = 1.2f; point.Y = 3.4f; 4 Generics public class List List<T> { T[] elements; private object[] elements; private int count; public void Add(object Add(T element) { element) { if (count == elements.Length) Resize(count * 2); elements[count++] = element; } public object T this[int index] { this[int index] { get { return elements[index]; } intList List intList List<int> = new= List(); new List<int>(); set { elements[index] = value; } } intList.Add(1); // Argument No boxing is boxed public int Count { get { return count; } } } intList.Add(2); intList.Add("Three"); // Argument No boxing is boxed // Compile-time Should be an error int i = intList[0]; (int)intList[0]; // No cast // Cast required required 5 Generics • 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 through reflection JIT compiler replaces generic IL with object references Specific to App Domain • Value types – Compiler will create one version for each value type (one for int, one for long, etc) – Reused for same value type • Reference types – Compiler will create one version for all reference types • Ex: Customer class, DataSet, Orders class – Reused in all further encounters of all other reference types 6 Generics • Type parameters can be applied to – Class, struct, interface, and 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<int,string> numberSpellings; 7 Generics • Type parameters can be applied to – Class, struct, interface, and delegate types – Methods class Utils { public static T[] CreateArray<T>(int size) { return new T[size]; } public static void SortArray<T>(T[] { string[] names = array) Utils.CreateArray<string>(3); … names[0] = "Jones"; } names[1] = "Anderson"; } names[2] = "Williams"; Utils.SortArray(names); 8 Generics • Type parameters can be applied to – Class, struct, interface, and delegate types – Methods • Type parameters can have constraints – One base class, multiple interfaces, new() class Dictionary<K,V>: Dictionary<K,V> where IDictionary<K,V> K: IComparable { where K: IComparable<K> public void where V: IKeyProvider<K>, Add(K key, V value) IPersistable, { new() { … public if (key.CompareTo(x) (((IComparable)key).CompareTo(x) void Add(K key, V== value) 0) {…} { == 0) {…} … } } 9 Generic Constraints • 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() public struct Point<T> : struct { public T X; public T Y; } Point<float> point; point.X = 1.2f; point.Y = 3.4f; 10 Generics • T.default void Foo<T>() { T x = null; T y = T.default; } // Error // Ok • Null checks • Type casts void Foo<T>(T x) { if (x == null) { throw new FooException(); } … } void Foo<T>(T x) { int i = (int)x; int j = (int)(object)x; } // Error // Ok 11 Generics in the .NET Framework • Collection classes LinkedList<T> List<T> Dictionary<K,V> SortedDictionary<K,V> Stack<T> Queue<T> • Collection interfaces • Collection base classes IList<T> IDictionary<K,V> ICollection<T> IEnumerable<T> IEnumerator<T> IComparable<T> IComparer<T> • Utility classes • Reflection Collection<T> KeyedCollection<T> ReadOnlyCollection<T> Nullable<T> EventHandler<T> Comparer<T> Native support in IL and CLR 12 Generics Performance What’s wrong with this code? SqlCommand cmd = new SqlCommand(); using (SqlDataReader rs = cmd.ExecuteReader()) { while (rs.Read()) Age { --------int Age; 30 Age = (int)rs["Age"]; 50 Console.WriteLine(Age); null } 21 } 14 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); } 15 Nullable Types • T? same as System.Nullable<T> • null literal conversions int? x = 123; double? y = 1.25; • Nullable conversions int? x = null; double? y = null; int i = 123; int? x = i; double? y = x; // int --> int? // int? --> double? 16 Anonymous Methods class MyForm : Form { ListBox listBox; TextBox textBox; Button addButton; public MyForm() { listBox = new ListBox(...); textBox = new TextBox(...); addButton = new Button(...); addButton.Click += delegate { new EventHandler(AddClick); listBox.Items.Add(textBox.Text); } }; }void AddClick(object sender, EventArgs e) { } listBox.Items.Add(textBox.Text); } } 17 Anonymous Methods • Allows code block in place of delegate • Delegate type automatically inferred – Code block can be parameterless – Or code block can have parameters – Return types must match button.Click += delegate { MessageBox.Show("Hello"); }; button.Click += delegate(object sender, EventArgs e) { MessageBox.Show(((Button)sender).Text); }; 18 Generic Delegates in the .NET Framework • Action - Performs an action on the specified object public sealed delegate void Action<T>( T obj ); • Predicate - Defines a set of criteria data must meet public sealed delegate bool Predicate<T>( T obj ); • Converter - Converts from one type to another type public sealed delegate U Converter<T, U>( T from ); • Comparison - Compares two objects of the same type public sealed delegate int Comparison<T>( T x, T y ); 19 List<T> Methods that use Generic Delegates • ForEach - Performs specified action on each element public void ForEach( Action<T> action ); • Find/FindIndex/FindAll/FindLast – Filters data based on condition public List<T> FindAll( Predicate<T> match ); • ConvertAll - Converts all to another type public List<U> ConvertAll<U>( Converter<T, U> converter ); • TrueForAll - Determines whether every element meets criteria in predicate public bool TrueForAll( Predicate<T> match ); 20 Using Anonymous Methods Generic List ForEach List<int> numbers = new List<int>(); numbers.Add(1); numbers.Add(1); numbers.Add(6); numbers.Add(2); int sum = 0; numbers.ForEach(delegate(int i) { sum += i; }); Console.WriteLine(sum); //Print 10 FindIndex int match = numbers.FindIndex(delegate(int i) { return i == 6; }); Console.WriteLine(match); //Print 2 TrueForAll bool check = numbers.TrueForAll(delegate(int i) { return i > 0; }); Console.WriteLine(check); //Print True 21 Anonymous Methods Iterators • foreach relies on “enumerator pattern” – GetEnumerator() method foreach (object obj in list) { DoSomething(obj); } Enumerator e = list.GetEnumerator(); while (e.MoveNext()) { object obj = e.Current; DoSomething(obj); } • foreach makes enumerating easy – But enumerators are hard to write! 23 Iterators public class ListEnumerator : IEnumerator { List list; int index; public class List { internal object[] elements; internal ListEnumerator(List list) { internal int count; this.list = list; index = -1; public ListEnumerator GetEnumerator() { } return new ListEnumerator(this); } 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]; } } } 24 Iterators public IEnumerator { • Method that incrementally computes and returns GetEnumerator() a return new __Enumerator(this); sequence of values } – yield return and yield break private class __Enumerator: IEnumerator – Must return IEnumerator or IEnumerable { object current; int state; public class List { public IEnumerator GetEnumerator() { for (int i = 0; i < count; i++) { yield return elements[i]; } } } public bool MoveNext() { switch (state) { case 0: … case 1: … case 2: … … } } public object Current { get { return current; } } } 25 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++) List<Item> items = GetItemList(); yield return elements[index + i]; foreach (Item x in items) {…} } foreach (Item x in items.Descending()) {…} } foreach (Item x in Items.Subrange(10, 20)) {…} 26 Iterators Partial Types public partial class Customer { public class Customer private int id; private string name; { private string address; private int id; private string name; private List<Orders> orders; private string address; } private List<Orders> orders; public partial class Customer public void SubmitOrder(Order order) { { orders.Add(order); public void SubmitOrder(Order order) { } orders.Add(order); } public bool HasOutstandingOrders() { return orders.Count > 0; public bool HasOutstandingOrders() { } return orders.Count } > 0; } } 28 Partial Types • Break source code into multiple source files – IDE generated vs custom code • IL emitted as if it is one file • No messy linking – csc customer1.cs customer2.cs • Can provide overloads in different classes – Signature must be different • Customer.Sell() • Customer.Sell(currency) • Both Web and Windows Forms use partial classes for Designer Generated code 29 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) {...} ... } 30 Property Accessors • Property accessor accessibility – Allows one accessor to be restricted further – Typically set {…} more restricted than get {…} public class Customer { private string _CustomerID; public string CustomerID { get { return id; } internal set { id = value; } } } 31 External Aliases • Enables use of identically named types in different assemblies namespace Stuff foo.dll extern alias Foo; { extern alias Bar; public class Utils { public class staticProgram void F() {...} { } static void Main() { } Foo.Stuff.Utils.F(); Bar.Stuff.Utils.F(); } namespace Stuff bar.dll } { public class/r:Foo=foo.dll Utils C:\>csc /r:Bar=bar.dll test.cs { public static void F() {...} } } 32 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 } } 33 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]; } 34 Resources • Visual C# Developer Center – http://msdn.microsoft.com/vcsharp/ • MSDN Forums – http://forums.msdn.com • Email – [email protected] 35 © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY. 36