390 likes | 540 Views
C #. Kit Colbert Student Consultant representing Microsoft mssc@brown.edu. C#. Design goals Unified type system Component-oriented features Productivity features C# futures Standardization. C# design goals. Dramatically increase productivity Provide unified and extensible type system
E N D
C# Kit Colbert Student Consultant representing Microsoft mssc@brown.edu
C# • Design goals • Unified type system • Component-oriented features • Productivity features • C# futures • Standardization
C# design goals • Dramatically increase productivity • Provide unified and extensible type system • Support component-oriented programming • Enable robust and durable applications • Build foundation for future innovation
Unified type system • Traditional views of primitive types • C++, Java: They’re “special” • Smalltalk, Lisp: They’re full-blown objects • C# unifies with no performance cost • Value types, boxing and unboxing • Deep simplicity throughout system • Improved extensibility and reusability • New primitive types: Decimal, SQL… • Collections, etc., work for all types
Value and reference types • Value types • Variables directly contain data • Cannot be null • Reference types • Variables contain references to objects • May be null int i = 123; string s = "Hello world"; i 123 s "Hello world"
Value and reference types • Value types • Primitives int i; double x; • Enums enum State { Off, On } • Structs struct Point { int x, y; } • Reference types • Classes class Foo: Bar, IFoo {...} • Interfaces interface IFoo: IBar {...} • Arrays Foo[] a = new Foo[10]; • Delegates delegate void Empty();
Classes • Inheritance • Single base class (System.Object) • Multiple interface implementations • Class members • Static and instance members • Nested types • Member access • Public, protected, internal, private
Structs • Like classes, except • Stored in-line, not heap allocated • Assignment copies data, not reference • Always inherit directly from System.Object • Ideal for light weight objects • Complex, Point, Rectangle, Color • int, float, double, etc., are all structs • No heap allocation, less GC pressure • More efficient use of memory
Classes and structs class CPoint { int x, y; ... } struct SPoint { int x, y; ... } CPoint cp = new CPoint(10, 20); SPoint sp = new SPoint(10, 20); 10 sp 20 cp CPoint 10 20
Unified type system • Boxing • Allocates box, copies value into it • Unboxing • Checks type of box, copies value out int i = 123; object o = i; int j = (int)o; 123 i System.Int32 o 123 123 j
Unified type system • Several benefits • Eliminates “wrapper classes” • Collection classes work with all types • Lots of examples in .NET Framework string s = string.Format( "On {0} your balance was {1}", date, balance); Hashtable t = new Hashtable(); t.Add(0, "zero"); t.Add(1, "one"); t.Add(2, "two");
Component-oriented features • What defines a component? • Properties, methods, events, attributes • C# has first class support • Not naming patterns, adapters, etc. • Not external files • Components are easy to build and consume
Properties • First class language construct public class Button: Control { private string text; public string Text { get { return text; } set { text = value; Repaint(); } } } Button b = new Button(); b.Text = "OK"; string s = b.Text;
Events • First class language construct public delegate void EventHandler( object sender, EventArgs e); public class Button: Control{ public event EventHandler Click; protected void OnClick(EventArgs e) { if (Click != null) Click(this, e); } } void Initialize() { Button b = new Button(...); b.Click += new EventHandler(ButtonClick); } void ButtonClick(object sender, EventArgs e) { MessageBox.Show("You pressed the button"); }
Attributes • How do you associate information with types and members? • Category of a property • Transaction context for a method • XML persistence mapping • Traditional solutions • Add keywords or pragmas to language • Use external files (e.g., .IDL, .DEF) • C# solution: Attributes
Attributes public class Button: Control { [Category("Appearance")] [Description("Color of text in button")] [Browsable(true)] public Color TextColor {...} protected override void Paint(Graphics g) { TextOut(g.GetHdc(), 10, 10, "Hello"); } [DllImport("gdi32", CharSet = CharSet.Auto)] static extern bool TextOut(int hDC, int x, int y, string text); } public class CategoryAttribute: System.Attribute { public readonly string Value; public CategoryAttribute(string s) { Value = s; } } Type type = typeof(Button); foreach (Attribute a in type.GetCustomAttributes()) { CategoryAttribute ca = a as CategoryAttribute; if (ca != null) { Console.WriteLine(ca.Value); } }
Attributes • Completely extensible • New attributes are created by inheriting from System.Attribute • Type-safe • Arguments checked at compile-time • Examined using reflection at run-time • Extensive use in .NET frameworks • XML, Web Services, security, serialization, component model, COM and P/Invoke interop, code configuration…
Productivity features • parameter arrays • ref and out parameters • overflow checking • foreach statement • using statement • switch on string
Parameter arrays • Can write “printf” style methods • Type-safe, unlike C++ static void printf(string fmt, params object[] args) { foreach (object x in args) { ... } } printf("%s %i", s, i); object[] args = new object[2]; args[0] = s; args[1] = i; printf("%s %i", args);
ref and out parameters • Use “ref” for in/out parameter passing • Use “out” to return multiple values • Must repeat ref/out at call site static void Swap(ref int a, ref int b) {...} static void Divide(int dividend, int divisor, out int result, out int remainder) {...} static void Main() { int x = 1, y = 2; Swap(ref x, ref y); }
Overflow checking • Integer arithmetic operations • C, C++, Java silently overflow • checked vs. unchecked contexts • Default is unchecked, except for constants • Change with “/checked” compiler switch int i = checked(x * y); checked { int i = x * y; }
foreach statement • Iteration of arrays • Iteration of IEnumerable collections public static void Main(string[] args) { foreach (string s in args) Console.WriteLine(s); } ArrayList accounts = Bank.GetAccounts(...); foreach (Account a in accounts) { if (a.Balance < 0) Console.WriteLine(a.CustName); }
using statement static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName); try { Stream output = File.Create(destName); try { byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } } finally { output.Close(); } } finally { input.Close(); } } static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName); Stream output = File.Create(destName); byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } output.Close(); input.Close(); } static void Copy(string sourceName, string destName) { using (Stream input = File.OpenRead(sourceName)) using (Stream output = File.Create(destName)) { byte[] b = new byte[65536]; int n; while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n); } } }
using statement • Acquire, Execute, Release pattern • Works with any IDisposable object • Data access classes, streams, text readers and writers, network classes, etc. using (Resource res = new Resource()) { res.DoWork(); } Resource res = new Resource(...); try { res.DoWork(); } finally { if (res != null) ((IDisposable)res).Dispose(); }
Switch on string Color ColorFromFruit(string s) { switch(s.ToLower()) { case "apple": return Color.Red; case "banana": return Color.Yellow; case "carrot": return Color.Orange; default: throw new InvalidArgumentException(); } }
C# futures • Generics • Iterators • Anonymous methods • Partial types
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<ItemType> { private ItemType[] elements; private int count; public void Add(ItemType element) { if (count == elements.Length) Resize(count * 2); elements[count++] = element; } public ItemType 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
Generics • Why generics? • Compile-time type checking • Performance (no boxing, no downcasts) • Reduced code bloat (typed collections) • C# generics vs. C++ templates • C# generics are checked at declaration • C# generics are instantiated at run-time • C# generics vs. proposed Java generics • C# generics work over entire type system • C# generics preserve types at run-time
Generics • Type parameters can be applied to • Class, struct, interface, and delegate types class Dictionary<KeyType, ValueType> {...} struct Pair<FirstType, SecondType> {...} interface IComparer<T> {...} delegate ResType Func<ArgType, ResType>(ArgType arg); Dictionary<string, Customer> customerLookupTable; Dictionary<string, List<Order>> orderLookupTable; Dictionary<int, string> numberSpellings;
Generics • Type parameters can be applied to • Class, struct, interface, and delegate types • Methods class Array{ public static T[] Create<T>(int size) { return new T[size]; } public static void Sort<T>(T[] array) { ... } } string[] names = Array.Create<string>(3); names[0] = "Jones"; names[1] = "Anderson"; names[2] = "Williams"; Array.Sort(names);
Generics • Constraints • One base class, multiple interfaces • Specified using “where” clause interface IComparable { int CompareTo(object obj); } class Dictionary<K, V> { public void Add(K key, V value) { ... switch (((IComparable)key).CompareTo(x)) { ... } } } interface IComparable { int CompareTo(object obj); } class Dictionary<K, V> where K: IComparable { public void Add(K key, V value) { ... switch (key.CompareTo(x)) { ... } } } interface IComparable<T> { int CompareTo(T obj); } class Dictionary<K, V>: IDictionary<K, V> where K: IComparable<K>, V: IKeyProvider<K>, V: IPersistable { ...}
Iterators • foreach relies on “enumerator pattern” • GetEnumerator() method returning object with a MoveNext() method and a Current property • 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); }
Iterators public class ListEnumerator { List list; int index; object current; internal ListEnumerator(List list) { this.list = list; } public bool MoveNext() { if (index >= list.count) { current = null; return false; } current = list.elements[index++]; return true; } public object Current { get { return current; } } } public class List { internal object[] elements; internal int count; public ListEnumerator GetEnumerator() { return new ListEnumerator(this); } }
Iterators public IEnumerator<T> GetEnumerator() { return new __Enumerator(this); } private class __Enumerator: IEnumerator<T>{ public bool MoveNext() { switch (state) { case 0: ...; case 1: ...; case 2: ...; ... } } public T Current {...} } • foreach member • Logical counterpart of foreach statement • yield statement • Produces next value in foreach statement public class List { internal object[] elements; internal int count; public object foreach() { for (int i = 0; i < count; i++) yield elements[i]; } }
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 += new EventHandler(sender, e) { listBox.Items.Add(textBox.Text); }; } }
Anonymous methods public class Bank { ArrayList accounts; ArrayList GetLargeAccounts(double minBalance) { return accounts.Select(new Filter( new MinBalanceSelector(minBalance).Matches)); } class MinBalanceSelector { double minBalance; public MinBalanceSelector(double minBalance) { this.minBalance = minBalance; } public bool Matches(object obj) { return ((Account)obj).Balance >= minBalance; } } } delegate bool Filter(object obj); public class ArrayList { public ArrayList Select(Filter matches) { ArrayList result = new ArrayList(); foreach (object obj in this) { if (matches(obj)) result.Add(obj); } return result; } } public class Bank { ArrayList accounts; ArrayList GetLargeAccounts(double minBalance) { return accounts.Select(...); } } public class Bank { ArrayList accounts; ArrayList GetLargeAccounts(double minBalance) { return accounts.Select( new Filter(a) { return ((Account)a).Balance >= minBalance; }); } }
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; } }
C# and CLI standardization • Work begun in September 2000 • Intel, HP, IBM, Fujitsu, Plum Hall, and others • ECMA standards ratified in December 2001 • Fast track to ISO • Several CLI and C# implementations • .NET Framework and Visual Studio .NET • “SSCLI” – Shared source on XP, FreeBSD, OS X • “Mono” – Open source on Linux • Standardization of new features ongoing
Q & A • .NET Framework SDK (includes C# compiler) • http://msdn.microsoft.com/netframework • Microsoft Visual C# .NET • http://msdn.microsoft.com/vcsharp • ECMA C# Standard • http://www.ecma.ch/ecma1/stand/ecma-334.htm • Microsoft Research Generics prototype • http://research.microsoft.com/projects/clrgen • Whitepaper on future C# language features • http://www.csharp.net • NUnit unit-testing framework for .NET • http://www.nunit.org