8º Simpósio Brasileiro de Linguagens de Programação C# e Programação Genérica Joel Pereira...

Post on 16-Apr-2015

111 views 4 download

Transcript of 8º Simpósio Brasileiro de Linguagens de Programação C# e Programação Genérica Joel Pereira...

8º Simpósio Brasileiro de Linguagens de Programação

C# e ProgramaC# e Programação ção GenéricaGenéricaC# e ProgramaC# e Programação ção GenéricaGenérica

Joel Pereira (joelcdp@microsoft.com)Joel Pereira (joelcdp@microsoft.com)Software Design EngineerSoftware Design EngineerWinFS API TeamWinFS API TeamMicrosoft CorporationMicrosoft Corporation

ConteúdoConteúdo

Baseado na versão Visual Studio Baseado na versão Visual Studio 2005, Community Release – Maio de 2005, Community Release – Maio de 20042004

Material disponibilizado pelo time C#Material disponibilizado pelo time C#Anders HejlsbergAnders Hejlsberg

Eric GunnersonEric Gunnerson

Novidades Novidades da Linguagem da Linguagem C#C#

Programação GenéricaProgramação Genérica

Tipos NullableTipos Nullable

Métodos Anonimos Métodos Anonimos

IteratorsIterators

Tipos ParciaisTipos Parciais

Classe EstClasse Estááticatica

Entre outras…Entre outras…

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

Programação GenéricaProgramação Genéricapublic 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

Programação GenéricaProgramação Genérica

Porque?Porque?Verificação de tipos em tempo de compilação Verificação de tipos em tempo de compilação

DesempenhoDesempenho

Redução de códigoRedução de código

Como Como é implementadoé implementado??Instanciado em tempo de execução, não Instanciado em tempo de execução, não compilaçãocompilação

Verificação na declaração, não na instanciaçãoVerificação na declaração, não na instanciação

Funciona para tipos referências e valoresFunciona para tipos referências e valores

Informação em tempo de execuçãoInformação em tempo de execução

Programação GenéricaProgramação Genérica

Parametros tipo podem ser Parametros tipo podem ser especificados paraespecificados para

Class, struct, interface, e delegate Class, struct, interface, e delegate

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;

Programação GenéricaProgramação Genérica

Parametros tipo podem ser Parametros tipo podem ser especificados paraespecificados para

Class, struct, interface, e delegateClass, struct, interface, e delegate

MétodosMétodosclass 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>(10);Utils.CreateArray<string>(10);names[0] = "Jones";names[0] = "Jones";……Utils.SortArray(names);Utils.SortArray(names);

Programação GenéricaProgramação Genérica

Parametros tipo podem ser Parametros tipo podem ser especificados paraespecificados para

Class, struct, interface, e delegate Class, struct, interface, e delegate

MétodosMétodos

Parametros tipo podem ter Parametros tipo podem ter constraintsconstraints

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

Programação GenéricaProgramação Genérica

Constraint PrimariaConstraint Primaria"class", or "struct""class", or "struct"

Constraint SecondariaConstraint SecondariaInterface ou parametro tipoInterface ou parametro tipo

Constraint de instanciaçãoConstraint de instanciação"new()""new()"

class Link<T> where T: class {…}class Link<T> where T: class {…}

class Nullable<T> where T: struct {…}class Nullable<T> where T: struct {…}

class Relation<T,U> where T: class where U: class Relation<T,U> where T: class where U: T {…}T {…}

Programação GenéricaProgramação Genérica

Collection classesCollection classes

Collection interfacesCollection interfaces

Collection base classesCollection base classes

Utility classesUtility classes

ReflectionReflection

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>

DemoDemo

Programação Genérica Programação Genérica

Tipo NullableTipo Nullable

System.Nullable<T>System.Nullable<T>Possibilita que um tipo valor seja nullPossibilita que um tipo valor seja null

É uma struct que associa um T e um boolÉ uma struct que associa um T e um bool

public struct Nullable<T> where T: public struct Nullable<T> where T: structstruct{{ public Nullable(T value) {…}public Nullable(T value) {…} public T Value { get {…} }public T Value { get {…} } public bool HasValue { get {…} }public bool HasValue { get {…} } … …}}

Nullable<int> x = new Nullable<int> x = new Nullable<int>(123);Nullable<int>(123);……if (x.HasValue) if (x.HasValue) Console.WriteLine(x.Value);Console.WriteLine(x.Value);

Tipo NullableTipo Nullable

Síntaxe T?Síntaxe T?

Literal nullLiteral null

Lifted conversionsLifted conversions

Lifted operatorsLifted operators

Operador ??Operador ??

int? x = 123;int? x = 123;double? y = 1.0;double? y = 1.0;

int? x = null;int? x = null;double? y = null;double? y = null;

int i = 123;int i = 123;int? x = i;int? x = i;double? y = x;double? y = x;int? z = (int?)y;int? z = (int?)y;int j = (int)z;int j = (int)z;

int? x = int? x = GetNullableInt();GetNullableInt();int? y = int? y = GetNullableInt();GetNullableInt();int? z = x + y;int? z = x + y;int? x = GetNullableInt();int? x = GetNullableInt();

int? y = GetNullableInt();int? y = GetNullableInt();int z = (x + y) / (x – y) ?? int z = (x + y) / (x – y) ?? 0;0;

Métodos AnonimosMétodos Anonimosclass 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); };}; }}}}

Métodos AnonimosMétodos Anonimos

Permite bloco de código ao inves do Permite bloco de código ao inves do delegatedelegate

Infêrencia automatica do tipo de Infêrencia automatica do tipo de delegatedelegate

Bloco de código sem uso de parametrosBloco de código sem uso de parametros

Ou com parametrosOu com parametros

Em ambos os casos, tipo de retorno deve Em ambos os casos, tipo de retorno deve ser igualser igualbutton.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);};};

Métodos AnonimosMétodos Anonimos

Bloco de código pode acessar Bloco de código pode acessar variáveis locaisvariáveis locais

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

Métodos AnonimosMétodos Anonimos

Converção de métodosConverção de métodos

Tipo inferido quando possivelTipo inferido quando possivel

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(); }}}}

IteratorsIterators

foreach depende “enumerator foreach depende “enumerator pattern”pattern”

Método GetEnumerator() Método GetEnumerator()

foreach faz uma enumeração ficar foreach faz uma enumeração ficar fácil fácil

Mas enumeradores são dificeis de Mas enumeradores são dificeis de escrever!escrever!

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

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

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

Método que computa e retorna uma Método que computa e retorna uma sequência de valores sequência de valores incrementalmenteincrementalmente

yield return e yield breakyield return e yield break

Deve retornar um IEnumerator ou Deve retornar um IEnumerator ou IEnumerableIEnumerable

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

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

DemoDemo

Tipos ParciaisTipos Parciaispublic 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; }}}}

Classes EstáticasClasses Estáticas

Pode conter apenas membros Pode conter apenas membros estáticos estáticos

Não pode ser tipo de variável, Não pode ser tipo de variável, parâmetro, …parâmetro, …

System.Console, System.Console, System.Environment, …System.Environment, …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) {…}{…} … …}}

Acesso à PropriedadesAcesso à Propriedades

Diferentes níveis de acesso para Diferentes níveis de acesso para Get/SetGet/Set

Típica configuração set {…} mais Típica configuração set {…} mais restrito que get {…}restrito que 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; } }}}}

Aliases ExternosAliases Externos

Assemblies com nomes de tipo Assemblies com nomes de tipo idênticos idênticos

Versões diferentes do mesmo Versões diferentes do mesmo assemblyassembly

namespace Stuffnamespace Stuff{{ public class Utilspublic class Utils {{ public static void F() public static void F() {…}{…} }}}}

namespace Stuffnamespace Stuff{{ public class Utilspublic class Utils {{ public static void F() public static void F() {…}{…} }}}}

foo.dllfoo.dll bar.dllbar.dllextern alias Foo;extern alias Foo;extern alias Bar;extern alias Bar;

class Programclass 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 C:\>csc /r:Foo=foo.dll /r:Bar=bar.dll

test.cstest.cs

Namespace Alias Namespace Alias QualifiersQualifiers

A::B procura por A como namespace A::B procura por A como namespace aliasalias

global::X procura X no namespace global::X procura X no namespace global global 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"); }}}}

Controle de WarningControle de Warning

#pragma warning#pragma warning

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

ThreadingThreadingSemaphoreSemaphore

Resource counting for mutex’sResource counting for mutex’s// construct a semaphore with a count of 3// construct a semaphore with a count of 3

Semaphore sem = new Semaphore(3);Semaphore sem = new Semaphore(3);

private void UseResource {private void UseResource {

// Wait until a count is available…// Wait until a count is available…

sem.WaitOne(); sem.WaitOne(); // // the sem count is reduced by one the sem count is reduced by one

// other code …// other code …

// Release the count:// Release the count:

sem.Release(); sem.Release(); // // the count is incremented by one the count is incremented by one

ThreadingThreadingNamed EventsNamed Events

V1.0 and V1.1: Events can only signal V1.0 and V1.1: Events can only signal the same processthe same process

Whidbey: Named Events allow cross Whidbey: Named Events allow cross process communicationprocess communication

V1.0 and V1.1: Events can only signal V1.0 and V1.1: Events can only signal the same processthe same process

Whidbey: Named Events allow cross Whidbey: Named Events allow cross process communicationprocess communication

Public Class EventWaitHandle Inherits WaitHandle Public Sub New EventWaitHandle(initialState As

Boolean, type As EventType, name As String )

Longhorn and WinFX: Longhorn and WinFX: Re-Invigorating the Virtuous Re-Invigorating the Virtuous CycleCycle

• Applies .NET Framework goodness to core OS• Consistent, object oriented• Secure, reliable platform• Modern library and language designs

• Enables new class of applications all built on managed code• Fuels ecosystems for the next decade of growth

For More InformationFor More Information

Applied Microsoft .NET Applied Microsoft .NET Framework Framework Programming (Richter)Programming (Richter)

NET Framework NET Framework Standard Library Standard Library Annotated Reference, Annotated Reference, Vol. 1 (Abrams) Vol. 1 (Abrams) http://blogs.msdn.com/bradahttp://blogs.msdn.com/brada

Q & AQ & A

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