1 visual c# "whidbey": language enhancements anders hejlsberg distinguished engineer...

Post on 27-Mar-2015

213 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

Visual C# "Whidbey": Language Enhancements

Anders HejlsbergDistinguished EngineerMicrosoft Corporationandersh@microsoft.com

Session Code: TLS320

2

C# Language EnhancementsC# Language Enhancements

GenericsAnonymous methodsIteratorsPartial typesOther enhancements

GenericsAnonymous methodsIteratorsPartial typesOther enhancements

3

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) if (count == elements.Length) Resize(count * 2);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) if (count == elements.Length) Resize(count * 2);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 // Argument is boxedboxedintList.Add(2);intList.Add(2); // Argument is // Argument is boxedboxedintList.Add("Three");intList.Add("Three"); // Should be an // Should be an errorerror

int i = (int)intList[0];int i = (int)intList[0]; // Cast required// Cast required

ListList<int><int> intList = new List intList = new List<int><int>();();

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 // Compile-time errorerror

int i = intList[0];int i = intList[0]; // No cast required// No cast required

4

GenericsGenerics

Why generics?Type checking, no boxing, no downcastsReduced code bloat (typed collections)

How are C# generics implemented?Instantiated at run-time, not compile-timeChecked at declaration, not instantiationWork for both reference and value typesComplete run-time type information

Why generics?Type checking, no boxing, no downcastsReduced code bloat (typed collections)

How are C# generics implemented?Instantiated at run-time, not compile-timeChecked at declaration, not instantiationWork for both reference and value typesComplete run-time type information

5

GenericsGenerics

Type parameters can be applied toClass, struct, interface, and delegate types

Type parameters can be applied toClass, struct, interface, and 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> Dictionary<string,Customer> customerLookupTable;customerLookupTable;

Dictionary<string,List<Order>> Dictionary<string,List<Order>> orderLookupTable;orderLookupTable;

Dictionary<string,int> wordCount;Dictionary<string,int> wordCount;

6

GenericsGenerics

Type parameters can be applied toClass, struct, interface, and delegate typesMethods

Type parameters can be applied toClass, struct, interface, and delegate typesMethods

class Utilsclass Utils{{ public static T[] CreateArray<T>(int public static T[] CreateArray<T>(int size) {size) { return new T[size];return new T[size]; }}

public static void SortArray<T>(T[] public static void SortArray<T>(T[] array) {array) { … … }}}}

string[] names = string[] names = Utils.CreateArray<string>(3);Utils.CreateArray<string>(3);names[0] = "Jones";names[0] = "Jones";names[1] = "Anderson";names[1] = "Anderson";names[2] = "Williams";names[2] = "Williams";Utils.SortArray(names);Utils.SortArray(names);

7

GenericsGenerics

Type parameters can be applied toClass, struct, interface, and delegate typesMethods

Type parameters can have constraints

One base class, multiple interfaces, new()

Type parameters can be applied toClass, struct, interface, and delegate typesMethods

Type parameters can have constraints

One base class, multiple interfaces, new()

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) { … … }}}}

8

public class List<T>public class List<T>{{ public void Add(T item) public void Add(T item) {…}{…} public T this[int index] public T this[int index] {…}{…} … …}}

public class List<T>public class List<T>: IList: IList{{ public void Add(T item) public void Add(T item) {…}{…} public T this[int index] public T this[int index] {…}{…} … …}}

public interface IListpublic interface IList{{ public void Add(object public void Add(object item);item); public object this[int index] public object this[int index] {…}{…} … …}}

GenericsGenerics

Generics are “invariant”Interfaces can be used for type neutrality

Generics are “invariant”Interfaces can be used for type neutrality

List<objectList<object>>

List<int>List<int> List<stringList<string>>

objectobject

9

GenericsGenerics

T.default

Null checks

Type casts

T.default

Null checks

Type casts

void Foo<T>() {void Foo<T>() { T x = null;T x = null; // Error// Error T y = T.default;T y = T.default; // Ok// Ok}}

void Foo<T>(T x) {void Foo<T>(T x) { if (x == null) {if (x == null) { throw new throw new FooException();FooException(); }} … …}}

void Foo<T>(T x) {void Foo<T>(T x) { int i = (int)x;int i = (int)x; // // ErrorError int j = (int)(object)x;int j = (int)(object)x; // // OkOk}}

10

GenericsGenerics

Collection classes

Collection interfaces

Collection base classes

Utility classes

Reflection

Collection classes

Collection interfaces

Collection base classes

Utility classes

Reflection

List<T>List<T>Dictionary<K,V>Dictionary<K,V>SortedDictionary<K,VSortedDictionary<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<ReadOnlyCollection<T>T>

Nullable<T>Nullable<T>EventHandler<T>EventHandler<T>Comparer<T>Comparer<T>

11

GenericsGenerics

System.Nullable<T>Provides nullability for any typeStruct that combines a T and a boolConversions between T and Nullable<T>Conversion from null literal to Nullable<T>

System.Nullable<T>Provides nullability for any typeStruct that combines a T and a boolConversions between T and Nullable<T>Conversion from null literal to Nullable<T>

Nullable<int> x = 123;Nullable<int> x = 123;Nullable<int> y = null;Nullable<int> y = null;

int i = (int)x;int i = (int)x;int j = x.Value;int j = x.Value;

if (x.HasValue) if (x.HasValue) Console.WriteLine(x.Value);Console.WriteLine(x.Value);

12

Anonymous MethodsAnonymous Methods

class MyForm : Formclass MyForm : Form{{ ListBox listBox;ListBox listBox; TextBox textBox;TextBox textBox; Button addButton;Button addButton;

public MyForm() {public MyForm() { listBox = new ListBox(...);listBox = new ListBox(...); textBox = new TextBox(...);textBox = new TextBox(...); addButton = new Button(...);addButton = new Button(...); addButton.Click += addButton.Click += new new EventHandler(AddClick);EventHandler(AddClick); }}

void AddClick(object sender, EventArgs e) {void AddClick(object sender, EventArgs e) { listBox.Items.Add(textBox.Text);listBox.Items.Add(textBox.Text); }}}}

class MyForm : Formclass MyForm : Form{{ ListBox listBox;ListBox listBox; TextBox textBox;TextBox textBox; Button addButton;Button addButton;

public MyForm() {public MyForm() { listBox = new ListBox(...);listBox = new ListBox(...); textBox = new TextBox(...);textBox = new TextBox(...); addButton = new Button(...);addButton = new Button(...); addButton.Click += addButton.Click += delegate {delegate { listBox.Items.Add(textBox.Text);listBox.Items.Add(textBox.Text); };}; }}}}

13

Anonymous MethodsAnonymous Methods

Allows code block in place of delegateDelegate type automatically inferred

Code block can be parameterlessOr code block can have parametersIn either case, return types must match

Allows code block in place of delegateDelegate type automatically inferred

Code block can be parameterlessOr code block can have parametersIn either case, return types must match

button.Click += delegate button.Click += delegate { MessageBox.Show("Hello"); };{ MessageBox.Show("Hello"); };

button.Click += delegate(object sender, EventArgs button.Click += delegate(object sender, EventArgs e) {e) { MessageBox.Show(((Button)sender).Text); MessageBox.Show(((Button)sender).Text);};};

14

Anonymous MethodsAnonymous Methods

Code block can access local variablesCode block can access local variables

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> public List<T> FindAll(Predicate<T> filter) {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(delegate(Account a) {return accounts.FindAll(delegate(Account a) { return a.Balance < 0;return a.Balance < 0; });}); }}

List<Account> GetLargeAccounts(double List<Account> GetLargeAccounts(double minBalance) {minBalance) { return accounts.FindAll(delegate(Account a) {return accounts.FindAll(delegate(Account a) { return a.Balance >= minBalance;return a.Balance >= minBalance; });}); }}}}

public class Bankpublic class Bank{{ List<Account> GetLargeAccounts(double List<Account> GetLargeAccounts(double minBalance) {minBalance) { Helper helper = new Helper();Helper helper = new Helper(); helper.minBalance = minBalance;helper.minBalance = minBalance; return accounts.FindAll(return accounts.FindAll(helper.Matcheshelper.Matches);); }}

internal class Helperinternal class Helper {{ internal double minBalance;internal double minBalance;

internal bool Matches(Account a) {internal bool Matches(Account a) { return a.Balance >= minBalance;return a.Balance >= minBalance; }} }}}}

15

Anonymous MethodsAnonymous Methods

Method group conversionsDelegate type inferred when possibleMethod group conversionsDelegate 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 new ThreadStart(Work)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(); }}}}

16

Generics Performance

17

IteratorsIterators

foreach relies on “enumerator pattern”

GetEnumerator() method

foreach makes enumerating easyBut enumerators are hard to write!

foreach relies on “enumerator pattern”

GetEnumerator() method

foreach makes enumerating easyBut enumerators are hard to write!

foreach (object obj in list) {foreach (object obj in list) { DoSomething(obj);DoSomething(obj);}} Enumerator e = Enumerator e =

list.GetEnumerator();list.GetEnumerator();while (e.MoveNext()) {while (e.MoveNext()) { object obj = e.Current;object obj = e.Current; DoSomething(obj);DoSomething(obj);}}

18

IteratorsIterators

public class Listpublic class List{{ internal object[] elements;internal object[] elements; internal int count;internal int count;

public ListEnumerator public ListEnumerator GetEnumerator() {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]; } }}}}

19

public class Listpublic class List{{ public IEnumerator public IEnumerator GetEnumerator() {GetEnumerator() { for (int i = 0; i < count; i++) {for (int i = 0; i < count; i++) { yield return elements[i];yield return elements[i]; }} }}}}

IteratorsIterators

Method that incrementally computes and returns a sequence of values

yield return and yield breakMust return IEnumerator or IEnumerable

Method that incrementally computes and returns a sequence of values

yield return and yield breakMust return IEnumerator or IEnumerable

public IEnumerator GetEnumerator() public IEnumerator GetEnumerator() {{ return new __Enumerator(this);return new __Enumerator(this);}}

private class __Enumerator: private class __Enumerator: IEnumeratorIEnumerator{{ object current;object current; int state;int state;

public bool MoveNext() {public bool MoveNext() { switch (state) {switch (state) { case 0: …case 0: … case 1: …case 1: … case 2: …case 2: … … … }} }}

public object Current {public object Current { get { return current; }get { return current; } }}}}

20

public class List<T>public class List<T>{{ public IEnumerator<T> GetEnumerator() {public IEnumerator<T> GetEnumerator() { for (int i = 0; i < count; i++) yield return for (int i = 0; i < count; i++) yield return elements[i];elements[i]; }}

public IEnumerable<T> Descending() {public IEnumerable<T> Descending() { for (int i = count - 1; i >= 0; i--) yield return for (int i = count - 1; i >= 0; i--) yield return elements[i];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++) yield return for (int i = 0; i < n; i++) yield return elements[index + i];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)) {…}

21

Partial TypesPartial Typespublic partial class Customerpublic partial 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 partial class Customerpublic 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 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; }}}}

22

Partial Types

23

Other EnhancementsOther Enhancements

Static classesCan contain only static membersCannot be type of variable, parameter, etc.System.Console, System.Environment, etc.

Static classesCan contain only static membersCannot be type of variable, parameter, etc.System.Console, System.Environment, etc.

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) {…}{…} … …}}

24

Other EnhancementsOther Enhancements

Property accessor accessibilityAllows one accessor to be restricted furtherTypically set {…} more restricted than get {…}

Property accessor accessibilityAllows one accessor to be restricted furtherTypically set {…} more restricted than get {…}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; } }}}}

25

Other EnhancementsOther Enhancements

Namespace alias qualifierA::B looks up A only as namespace aliasglobal::X starts lookup in global namespace

Namespace alias qualifierA::B looks up A only as namespace aliasglobal::X starts lookup 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"); }}}}

26

Other EnhancementsOther Enhancements

Fixed size buffersC style embedded arrays in unsafe code

Fixed size buffersC style embedded 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];}}

27

Other EnhancementsOther Enhancements

#pragma warningControl individual warnings in blocks of code

#pragma warningControl individual warnings in blocks of code

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 }}}}

28

C# and CLI StandardizationC# and CLI Standardization

Work begun in September 2000Intel, HP, IBM, Fujitsu, Plum Hall, and others

ECMA standards ratified December 2001ISO standards published April 2003Several 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

Work begun in September 2000Intel, HP, IBM, Fujitsu, Plum Hall, and others

ECMA standards ratified December 2001ISO standards published April 2003Several 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

29Book signing, Exhibition Hall Book Store, Wednesday, 1-2pm

30

Q & AQ & A

C# Language home pagehttp://msdn.microsoft.com/vcsharp/language

ECMA C# Standardhttp://www.ecma-international.org/publications/standards/ecma-334.htm

Panel: The Future of .NET LanguagesPNL10, Thursday, 1:45pm – 3:15pm

Tools Lounge (near Hall A)Tuesday, 5:15pm – 6:30pmWednesday, 3:00pm – 5:00pm

C# Language home pagehttp://msdn.microsoft.com/vcsharp/language

ECMA C# Standardhttp://www.ecma-international.org/publications/standards/ecma-334.htm

Panel: The Future of .NET LanguagesPNL10, Thursday, 1:45pm – 3:15pm

Tools Lounge (near Hall A)Tuesday, 5:15pm – 6:30pmWednesday, 3:00pm – 5:00pm

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

top related