C e Programao Genrica Joel Pereira joelcdpmicrosoft com

  • Slides: 34
Download presentation
C# e Programação Genérica Joel Pereira (joelcdp@microsoft. com) Software Design Engineer Win. FS API

C# e Programação Genérica Joel Pereira (joelcdp@microsoft. com) Software Design Engineer Win. FS API Team Microsoft Corporation 8º Simpósio Brasileiro de Linguagens de Programação

Conteúdo Baseado na versão Visual Studio 2005, Community Release – Maio de 2004 Material

Conteúdo Baseado na versão Visual Studio 2005, Community Release – Maio de 2004 Material disponibilizado pelo time C# Anders Hejlsberg Eric Gunnerson

Novidades da Linguagem C# Programação Genérica Tipos Nullable Métodos Anonimos Iterators Tipos Parciais Classe

Novidades da Linguagem C# Programação Genérica Tipos Nullable Métodos Anonimos Iterators Tipos Parciais Classe Estática Entre outras…

Programação Genérica public class List<T> { private object[] T[] elements; private int count; public

Programação Genérica public class List<T> { private object[] T[] elements; private int count; public void Add(object T element) { { if (count == elements. Length) Resize(count * 2); elements[count++] = element; } } public object T this[int index] { { get { return elements[index]; } =List(); List<int> int. List = new List<int>(); set { elements[index] = value; } } int. List. Add(1); // No Argument boxing is boxed int. List. Add(2); // No Argument boxing is boxed public int Count {int. List. Add("Three"); // Compile-time Should be an error get { return count; } } int i = int. List[0]; (int)int. List[0]; // No Castcast required

Programação Genérica Porque? Verificação de tipos em tempo de compilação Desempenho Redução de código

Programação Genérica Porque? Verificação de tipos em tempo de compilação Desempenho Redução de código Como é implementado? Instanciado em tempo de execução, não compilação Verificação na declaração, não na instanciação Funciona para tipos referências e valores Informação em tempo de execução

Programação Genérica Parametros tipo podem ser especificados para Class, struct, interface, e delegate class

Programação Genérica Parametros tipo podem ser especificados para Class, struct, interface, e delegate class Dictionary<K, V> {…} struct Hash. Bucket<K, V> {…} interface IComparer<T> {…} customer. Lookup. Table; delegate RDictionary<string, Customer> Function<A, R>(A arg); Dictionary<string, List<Order>> order. Lookup. Table; Dictionary<string, int> word. Count;

Programação Genérica Parametros tipo podem ser especificados para Class, struct, interface, e delegate Métodos

Programação Genérica Parametros tipo podem ser especificados para Class, struct, interface, e delegate Métodos class Utils { public static T[] Create. Array<T>(int size) { return new T[size]; } public static void Sort. Array<T>(T[] array) { … string[] names = Utils. Create. Array<string>(10); } names[0] = "Jones"; } … Utils. Sort. Array(names);

Programação Genérica Parametros tipo podem ser especificados para Class, struct, interface, e delegate Métodos

Programação Genérica Parametros tipo podem ser especificados para Class, struct, interface, e delegate Métodos Parametros tipo podem ter constraints class Dictionary<K, V>: Dictionary<K, V> where IDictionary<K, V> K: IComparable { where K: IComparable<K> public V: where void IKey. Provider<K>, Add(K key, V value) IPersistable, { new() { … public if (key. Compare. To(x) ((IComparable)key). Compare. To(x) void Add(K key, V== value) 0) {…} { == 0) {…} … } }

Programação Genérica Constraint Primaria "class", or "struct" Constraint Secondaria Interface ou parametro tipo Constraint

Programação Genérica Constraint Primaria "class", or "struct" Constraint Secondaria Interface ou parametro tipo Constraint de instanciação "new()" class Link<T> where T: class {…} class Nullable<T> where T: struct {…} class Relation<T, U> where T: class where U: T {…}

Programação Genérica Collection classes List<T> Dictionary<K, V> Sorted. Dictionary<K, V> Stack<T> Queue<T> Collection interfaces

Programação Genérica Collection classes List<T> Dictionary<K, V> Sorted. Dictionary<K, V> Stack<T> Queue<T> Collection interfaces IList<T> IDictionary<K, V> ICollection<T> IEnumerable<T> IEnumerator<T> IComparable<T> IComparer<T> Collection base classes Utility classes Reflection Collection<T> Keyed. Collection<T> Read. Only. Collection<T> Nullable<T> Event. Handler<T> Comparer<T>

Demo Programação Genérica

Demo Programação Genérica

Tipo Nullable System. Nullable<T> Possibilita que um tipo valor seja null É uma struct

Tipo Nullable System. Nullable<T> Possibilita que um tipo valor seja null É uma struct que associa um T e um bool public struct Nullable<T> where T: struct { public Nullable(T value) {…} public T Value { get {…} } public bool Has. Value { get {…} } … } Nullable<int> x = new Nullable<int>(123); … if (x. Has. Value) Console. Write. Line(x. Value);

Tipo Nullable Síntaxe T? int? x = 123; double? y = 1. 0; Literal

Tipo Nullable Síntaxe T? int? x = 123; double? y = 1. 0; Literal null int? x = null; double? y = null; Lifted conversions Lifted operators Operador ? ? int i = 123; int? x = i; double? y = x; int? z = (int? )y; int j = (int)z; int? x = Get. Nullable. Int(); int? y = Get. Nullable. Int(); int? z = x + y; int? x = Get. Nullable. Int(); int? y = Get. Nullable. Int(); int z = (x + y) / (x – y) ? ? 0;

Métodos Anonimos class My. Form : Form { List. Box list. Box; Text. Box

Métodos Anonimos class My. Form : Form { List. Box list. Box; Text. Box text. Box; Button add. Button; public My. Form() { list. Box = new List. Box(. . . ); text. Box = new Text. Box(. . . ); add. Button = new Button(. . . ); add. Button. Click += delegate new Event. Handler(Add. Click); { } list. Box. Items. Add(text. Box. Text); }; }void Add. Click(object sender, Event. Args e) { } list. Box. Items. Add(text. Box. Text); } }

Métodos Anonimos Permite bloco de código ao inves do delegate Infêrencia automatica do tipo

Métodos Anonimos Permite bloco de código ao inves do delegate Infêrencia automatica do tipo de delegate Bloco de código sem uso de parametros Ou com parametros Em ambos os casos, tipo de retorno deve ser igual button. Click += delegate { Message. Box. Show("Hello"); }; button. Click += delegate(object sender, Event. Args e) { Message. Box. Show(((Button)sender). Text); };

Métodos Anonimos Bloco de código pode acessar variáveis public class Bank { locais public

Métodos Anonimos Bloco de código pode acessar variáveis public class Bank { locais public List<Account> class Bank Get. Large. Accounts(double min. Balance) { { Helper helper = new Helper(); delegate bool Predicate<T>(T List<Account> accounts; item); helper. min. Balance = min. Balance; return accounts. Find. All(helper. Matches); public. List<Account> class List<T> Get. Overdrawn. Accounts() { } { return accounts. Find. All(delegate(Account a) { public List<T> Find. All(Predicate <T> filter) { return a. Balance < 0; internal class Helper List<T> }); { result = new List<T>(); foreach (T item double in this) {min. Balance; } internal if (filter(item)) result. Add(item); } List<Account> Get. Large. Accounts(double internal bool Matches(Account a) { min. Balance) { return result; return accounts. Find. All(delegate(Account return a. Balance >= min. Balance; a) { } return a. Balance >= min. Balance; } } }); } }} }

Métodos Anonimos Converção de métodos Tipo inferido quando possivel using System; using System. Threading;

Métodos Anonimos Converção de métodos Tipo inferido quando possivel using System; using System. Threading; class Program { static void Work() {…} } static void Main() { Thread t = new Thread(Work new Thread. Start(Work) ); ); t. Start(); }

Iterators foreach depende “enumerator pattern” Método Get. Enumerator() foreach (object obj in list) {

Iterators foreach depende “enumerator pattern” Método Get. Enumerator() foreach (object obj in list) { Do. Something(obj); Enumerator e = list. Get. Enumerator(); } while (e. Move. Next()) { object obj = e. Current; Do. Something(obj); } foreach faz uma enumeração ficar fácil Mas enumeradores são dificeis de escrever!

Iterators public class List. Enumerator : IEnumerator { List list; int index; public class

Iterators public class List. Enumerator : IEnumerator { List list; int index; public class List { internal List. Enumerator(List list) { internal object[] elements; this. list = list; internal int count; index = -1; public List. Enumerator}Get. Enumerator() { return new List. Enumerator(this); public bool Move. Next() { } int i = index + 1; } if (i >= list. count) return false; index = i; return true; } } public object Current { get { return list. elements[index]; } }

Iterators Método que computapublic e retorna uma IEnumerator Get. Enumerator() { return new __Enumerator(this);

Iterators Método que computapublic e retorna uma IEnumerator Get. Enumerator() { return new __Enumerator(this); sequência de valores incrementalmente } private class __Enumerator: IEnumerator yield return e yield break { object current; Deve retornar um IEnumerator ou int state; IEnumerable public bool Move. Next() { switch (state) { public class List case 0: … { case 1: … public IEnumerator Get. Enumerator() { case 2: … … for (int i = 0; i < count; i++) { } yield return elements[i]; } } public object Current { } get { return current; } }

Iterators public class List<T> { public IEnumerator<T> Get. Enumerator() { for (int i =

Iterators public class List<T> { public IEnumerator<T> Get. Enumerator() { 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 = Get. Item. List(); foreach (Item x in items) {…} foreach (Item x in items. Descending()) {…} foreach (Item x in Items. Subrange(10, 20)) {…}

Demo

Demo

Tipos Parciais public partial class Customer { public class Customer private int id; private

Tipos Parciais 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 Submit. Order(Order order) { { orders. Add(order); public void Submit. Order(Order order) { } orders. Add(order); } public bool Has. Outstanding. Orders() { return orders. Count > 0; public bool Has. Outstanding. Orders() { } return orders. Count } > 0; } }

Classes Estáticas Pode conter apenas membros estáticos Não pode ser tipo de variável, parâmetro,

Classes Estáticas Pode conter apenas membros estáticos Não pode ser tipo de variável, parâmetro, … System. Console, System. Environment, … public static class Math { public static double Sin(double x) {…} public static double Cos(double x) {…} … }

Acesso à Propriedades Diferentes níveis de acesso para Get/Set Típica configuração set {…} mais

Acesso à Propriedades Diferentes níveis de acesso para Get/Set Típica configuração set {…} mais restrito que get {…} public class Customer { private string id; } public string Customer. Id { get { return id; } internal set { id = value; } }

Aliases Externos Assemblies com nomes de tipo idênticos Versões diferentes do mesmo assembly foo.

Aliases Externos Assemblies com nomes de tipo idênticos Versões diferentes do mesmo assembly foo. dll bar. dll extern alias Foo; extern alias Bar; namespace Stuff { { class Program public class Utils { { static void Main() { public static. Foo. Stuff. Utils. F void F() {…} (); public static void F() {…} } } Bar. Stuff. Utils. F(); } } C: >csc /r: Foo=foo. dll /r: Bar=bar. dll test. cs

Namespace Alias Qualifiers A: : B procura por A como namespace alias global: :

Namespace Alias Qualifiers A: : B procura por A como namespace alias global: : X procura X no namespace global using IO = System. IO; class Program { static void Main() { IO: : Stream s = new IO: : File. Open. Read("foo. txt"); global: : System. Console. Write. Line("Hello"); } }

Controle de Warning #pragma warning using System; class Program { [Obsolete] static void Foo()

Controle de Warning #pragma warning using System; class Program { [Obsolete] static void Foo() {} static void Main() { #pragma warning disable 612 Foo(); #pragma warning restore 612 } }

Threading Semaphore Resource counting for mutex’s // construct a semaphore with a count of

Threading Semaphore Resource counting for mutex’s // construct a semaphore with a count of 3 Semaphore sem = new Semaphore(3); private void Use. Resource { // Wait until a count is available… sem. Wait. One(); // the sem count is reduced by one // other code … // Release the count: sem. Release(); // the count is incremented by one

Threading Named Events V 1. 0 and V 1. 1: Events can only signal

Threading Named Events V 1. 0 and V 1. 1: Events can only signal the same process Whidbey: Named Events allow cross process communication Public Class Event. Wait. Handle Inherits Wait. Handle Public Sub New Event. Wait. Handle(initial. State As Boolean, type As Event. Type, name As String )

Longhorn and Win. FX: Re-Invigorating the Virtuous Cycle • Applies. NET Framework goodness to

Longhorn and Win. FX: Re-Invigorating the Virtuous Cycle • 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 Information Applied Microsoft. NET Framework Programming (Richter) NET Framework Standard Library Annotated

For More Information Applied Microsoft. NET Framework Programming (Richter) NET Framework Standard Library Annotated Reference, Vol. 1 (Abrams) http: //blogs. msdn. com/brada

Q&A

Q&A

© 2004 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only.

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