C# e Programação Genérica
Joel Pereira ( [email protected])
Software Design Engineer
WinFS 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 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 Estática
Entre outras…
Programação Genérica
public class List<T>
List
{
private object[]
T[] elements;
elements;
private int count;
public void Add(T
Add(object
element)
element)
{
{
if (count == elements.Length) Resize(count * 2);
elements[count++] = element;
}
}
public object
T this[int
this[int
index]
index]
{
{
get { return elements[index];
} =List();
List intListintList
List<int>
= new
new List<int>();
set { elements[index] = value; }
}
intList.Add(1);
// No
Argument
boxing is boxed
intList.Add(2);
// No
Argument
boxing is boxed
public int Count {intList.Add("Three");
// Compile-time
Should be an error
error
get { return count; }
}
int i = intList[0];
(int)intList[0];
// No
Castcast
required
required
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 Dictionary<K,V> {…}
struct HashBucket<K,V> {…}
interface IComparer<T> {…}
customerLookupTable;
delegate RDictionary<string,Customer>
Function<A,R>(A arg);
Dictionary<string,List<Order>> orderLookupTable;
Dictionary<string,int> wordCount;
Programação Genérica
Parametros tipo podem ser especificados
para
Class, struct, interface, e delegate
Métodos
class Utils
{
public static T[] CreateArray<T>(int size) {
return new T[size];
}
public static void SortArray<T>(T[] array) {
…
string[] names = Utils.CreateArray<string>(10);
}
names[0] = "Jones";
}
…
Utils.SortArray(names);
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
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) {…}
…
}
}
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>
SortedDictionary<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>
KeyedCollection<T>
ReadOnlyCollection<T>
Nullable<T>
EventHandler<T>
Comparer<T>
Demo
Programação Genérica
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 HasValue { get {…} }
…
}
Nullable<int> x = new Nullable<int>(123);
…
if (x.HasValue) Console.WriteLine(x.Value);
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 = GetNullableInt();
int? y = GetNullableInt();
int? z = x + y;
int? x = GetNullableInt();
int? y = GetNullableInt();
int z = (x + y) / (x – y) ?? 0;
Métodos Anonimos
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);
}
}
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 { MessageBox.Show("Hello"); };
button.Click += delegate(object sender, EventArgs e) {
MessageBox.Show(((Button)sender).Text);
};
Métodos Anonimos
Bloco
de código pode acessar variáveis
public class Bank
{
locais
public List<Account>
class Bank
GetLargeAccounts(double minBalance) {
{
Helper helper = new Helper();
delegate
bool
Predicate<T>(T
List<Account>
accounts; item);
helper.minBalance
= minBalance;
return accounts.FindAll(helper.Matches);
publicList<Account>
class
List<T>
GetOverdrawnAccounts() {
}
{
return accounts.FindAll(delegate(Account a) {
public List<T>
FindAll(Predicate<T>
filter) {
return a.Balance
< 0;
internal
class Helper
List<T>
});{ result = new List<T>();
foreach
(T item double
in this) {minBalance;
}
internal
if (filter(item)) result.Add(item);
} List<Account>
GetLargeAccounts(double
internal bool
Matches(Account a) { minBalance) {
return
result;
return
accounts.FindAll(delegate(Account
return
a.Balance >= minBalance; a) {
}
return
a.Balance >= minBalance;
}
}
});}
}}
}
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);
Thread(new ThreadStart(Work));
t.Start();
}
Iterators
foreach depende “enumerator pattern”
Método GetEnumerator()
foreach (object obj in list) {
DoSomething(obj);
Enumerator e = list.GetEnumerator();
}
while (e.MoveNext()) {
object obj = e.Current;
DoSomething(obj);
}
foreach faz uma enumeração ficar fácil
Mas enumeradores são dificeis de escrever!
Iterators
public class ListEnumerator : IEnumerator
{
List list;
int index;
public class List
{
internal ListEnumerator(List list) {
internal object[] elements;
this.list = list;
internal int count;
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]; }
}
Iterators
Método que computapublic
e retorna
uma
IEnumerator GetEnumerator()
{
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 MoveNext() {
switch (state) {
public class List
case 0: …
{
case 1: …
public IEnumerator GetEnumerator() { 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> 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++) yield return elements[index + i];
}
}
List<Item> items = GetItemList();
foreach (Item x in items) {…}
foreach (Item x in items.Descending()) {…}
foreach (Item x in Items.Subrange(10, 20)) {…}
Demo
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 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;
}
}
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 restrito que
get {…}
public class Customer
{
private string id;
}
public string CustomerId {
get { return id; }
internal set { id = value; }
}
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
namespace Stuff
{
{
class Program
public class
public class Utils
{ Utils
{
{
static void Main() {
public staticFoo.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::X procura X no namespace global
using IO = System.IO;
class Program
{
static void Main() {
IO::Stream s = new IO::File.OpenRead("foo.txt");
global::System.Console.WriteLine("Hello");
}
}
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 3
Semaphore sem = new Semaphore(3);
private void UseResource {
// Wait until a count is available…
sem.WaitOne(); //  the sem count is reduced by one
// other code …
// Release the count:
sem.Release(); //  the count is incremented by one
Threading
Named Events
V1.0 and V1.1: Events can only signal the
same process
Whidbey: Named Events allow cross
process communication
Public Class EventWaitHandle Inherits WaitHandle
Public Sub New EventWaitHandle(initialState As
Boolean, type As EventType, name As String )
Longhorn and WinFX:
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
Reference, Vol. 1 (Abrams)
http://blogs.msdn.com/brada
Q&A
© 2004 Microsoft Corporation. All rights reserved.
This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.
Download

ppt - SBLP 2004