C#4 – O que há de novoGiovanni Bassigiggio@giggio.nethttp://giovannibassi.comhttp://unplugged.giggio.net
Giovanni BassiArquiteto de software
Microsoft MVP
Consultoria, gestão, mentoring
Treinamento
C#, VB, J#, F#, IronRuby, etc... (Beta a beta)
Dezenas de artigos na .Net Magazine
Editor técnico da .Net Magazine
Palestrante
Professor universitário
Líder e fundador do .Net Architects (1º grupo de arquitetura de software com .Net do Brasil)
InetaboardmemberMenos de oito meses de vida
Cerca de sete mil mensagens desde sua criação
Em torno de mil mensagens por mês
Cerca de 350 membros online
11 reuniões presenciais até agora
Revista a caminho
Podcast recentemente liberado
Efetivamente um dos maiores e mais ativos grupos do país
100 pessoas presentes no último (e primeiro) evento
Próxima reunião em 8 de Agosto, falando sobre OSLO com Waldemir Cambiucci (arquiteto Microsoft)Email: giggio@giggio.net
Blog técnico: http://unplugged.giggio.net
Site: http://giovannibassi.com
Twitter: @giovannibassi
.Net Architects: Grupo: http://dotnetarchitects.netPodcast: http://podcast.dotnetarchitects.netOnline: http://tinyurl.com/DotNetArchTwitter: #DotNetArchitectsOnline @
Agenda
Ferramental eEvolução
FerramentalC# 4.0 (Visual C# 2010) está presente no Visual Studio 2010 Beta 1 lançado em MaioDownload do Beta tem apenas 1.3 GB, disponível em:http://tinyurl.com/vs10b1Também no VS10:VB XF#DLR (suporte para IronRuby, IronPython, etc...)
Evolução do C#
C# e VBLado a Lado com VBSem separação de perfil de desenvolvedor(Mas não espere XML Literals no C# )
Quatro Grandes NovidadesConstruções dinâmicasArgumentos opcionais e argumentos nomeadosVariância para tipos genéricosMelhorias na interoperabilidade com o COM
Argumentos opcionais
EsclarecendoArgumentos opcionaisPermite omitir argumentos na chamada de uma função, usando valores padrãoArgumentos nomeadosPermite dizer os nomes dos argumentos em uma chamada de funçãoIgualzinho há no VB.Net desde o .Net 1.0 e VB 7 (2002)
VB (criando o método):PublicClass ElevadorPublicSub Subir( _OptionalByVal andares AsInteger = 1, _OptionalByVal velocidade AsInteger = 1)EndSubEndClass
Chamada: como era antes?var elevador = newElevador();elevador.Subir(1,1); //Obrigatório informar
Chamada: como é agora?var elevador = newElevador();elevador.Subir();
Declaração: como era antes?publicclassElevadorCS    {publicvoid Subir()        {this.Subir(1, 1);        }publicvoid Subir(int andares)        {this.Subir(andares, 1);        }publicvoid Subir(int andares, int velocidade)        {        }    }
Declaração: como é agora?publicclassElevadorCS    {publicvoid Subir(int andares = 1, int velocidade = 1)        {        }    }
Vantagens e desvantagensVantagensMais claroMais explícitoMais simplesDesvantagensSe mal usado pode incentivar métodos com parâmetros demais
RegrasParâmetros opcionais são os últimos do métodoSomente constantespublicvoid Subir(int andares = 1, int velocidade){}publicvoid Subir(int andares, int velocidade =ObterVelocidade()){}
Argumentos nomeados
Como era antes?var elevador2 = newElevadorCS();elevador2.Subir(2, 3);
Como é agora?var elevador2 = newElevadorCS();elevador2.Subir();elevador2.Subir(velocidade: 2);elevador2.Subir(velocidade: 2,andares: 3);
RegrasVocê pode nomear qualquer argumento, seja ele opcional ou nãoArgumentos nomeados podem ser chamados em qualquer ordemAs chamadas são feitas na ordem em que são declaradas do chamador, e não na funçãopublicvoid Subir(int andares = 1, int velocidade = 1) {}elevador2.Subir(                velocidade: this.ObterVelocidade(),                 andares: this.ObterAndares()                );PrimeiroSegundo
Argumentos opcionais e nomeados
C# dinâmico
MotivaçãoMotivaçãoHype das linguagens dinâmicasProdutividadeTestesInteroperabilidadeExtensibilidade
ExemploTeste com Cucumber e RSpec (IronRuby):Feature: Search courses  In order to ensure better utilization of courses  Potential students should be able to search for courses  Scenario: Search by topic    Given there are 240 courses which do not have the topic "biology"    And there are 3 courses A,B,C that each have "biology" as one of the topics    When I search for "biology"    Then I should see the following courses:      | title |      | A     |      | B     |      | C     |
Entendendo a infraDynamicLanguage Runtime (DLR) agora é parte da BCLMicrosoft.CSharp é obrigatória para trabalhar com dynamicSomente no .Net 4.0
Entendendo o dynamicTipos são “estáticamentetipados como dinâmicos”Tipos dinâmicos são System.Object’sTipos dinâmicos se propagam nas chamadasTipos dinâmicos não possuem checagem em tempo de compilação ou Intelisense
Exemplosdynamic d;dynamic d1 = 3;d1 = DateTime.Now;d.QualquerCoisa(3);Console.Writeline(d[10]);d.Propriedade1 = d.Propriedade2;d += 1;var a = d + Datetime.Now();d("algumparâmetro", 3);var d2 = d.AlgumValor();var d3 = ObterVariavelDinamica();
Entendendo o StaticDispatchÉ o comum até o C# 3.0Ligação forte com o método sendo chamadoSem perda de performance
Entendendo o DynamicDispatchA resolução do método é feita em tempo de execuçãoSe for uma chamada sobre um tipo dinâmico (dynamicreceiver), a chamada é dinâmica (ligada em runtime)Se for uma chamada sobre um tipo e método estáticos (staticreceiver), mas houver um parâmetro dinâmico, também é uma chamada dinâmica (ligada em runtime)
CuidadoO que acontece aqui?staticintFuncao(int z) { return 1; }staticvoid Main(){dynamic x = 3;DateTime y = Funcao(x);}
DynamicDispath != Virtual DispathSó pra constar, porque não vai dar tempo de explicarVejam uma discussão no .Net Architects:http://tinyurl.com/virtualdispatch
Como o DLR encontra o métodoVerifica o cache de chamadas, se houver, utilizaSe o objeto for um IDynamicMetaObjectProvider, utiliza sua implementaçãoSe não for, utiliza o Binder do C#, no caso, com ReflectionSe não achar: RuntimeBinderException
Resolução de sobrecargas (overloads)Mesma regra: se a chamada do método for dinâmica, o overload é avaliados somente em runtimeO DLR busca uma assinatura idêntica no cacheSe houver ele usa, senão ele busca uma converter os parâmetros, e achando, guarda no cacheSe não achar: RuntimeBinderException
Static e DinamicDispatch no Reflector
ExemplopublicclassConversor{publicvoid Converter(string x) { }publicvoid Converter(decimal x) { }}publicclassSuperConversor : Conversor{publicvoid Converter(int x) { }}
PegadinhaQual sobrecarga é chamada em cada caso?Conversor c1 = newSuperConversor();inti = 10;c1.Converter(i);Conversor c2 = newSuperConversor();dynamic d1 = 10;c2.Converter(d1);
RespostapublicclassConversor{publicvoid Converter(string x) { }publicvoid Converter(decimal x) { }}publicclassSuperConversor : Conversor{publicvoid Converter(int x) { }}
Regra 1A idéia é replicar o comportamento estático, como se as chamadas não fossem dinâmicas
Regra 2Dynamic é um Object. Cuidado com Boxing e Unboxing.dynamic d = new AlgumaClasse();d.s = default(S);d.s.i = 6;S é uma structi é um campo inteiro da structValendo mil reais…Qual o valor de i?
Não funcionamMétodos de extensãoLINQ (depende de métodos de extensão)
C# dinâmico
COM Interop
NovidadesNão precisamos mais da palavra-chave ref(o compilador coloca sozinho)Não precisamos de cast de tipos de valor para objectCom o suporte de parâmetros opcionais e nomeados, passamos só o necessárioIgualzinho ao que há no VB.Net desde o .Net 1.0 e VB 7 (2002)Temos ainda opção de mesclar o assembly de interop
Como era antes?ApplicationClassWordApp = newApplicationClass();  WordApp.Visible = true;  objectmissing = System.Reflection.Missing.Value;  objectreadOnly = false;  objectfileName = "Documento.docx";  Word.Documentdoc = WordApp.Documents.Open(reffileName, refmissing, refreadOnly,refmissing, refmissing, refmissing,refmissing, refmissing, refmissing,refmissing, refmissing, refmissing,refmissing, refmissing, refmissing);
Como é no VB?DimWordApp = New Word.ApplicationClass()WordApp.Visible = TrueDimfileName = "Documento.docx"DimdocAsDocument = _WordApp.Documents.Open( _fileName:=fileName, ReadOnly:=True)
Como é agora?varWordApp = newApplicationClass();  WordApp.Visible = true;  stringfileName = "Documento.docx";  vardoc = WordApp.Documents.Open(fileName, ReadOnly:false);
VB e C# lado a lado:varWordApp = newApplicationClass();  WordApp.Visible = true;  stringfileName = "Documento.docx";  vardoc = WordApp.Documents.Open(fileName, ReadOnly:false);C#DimWordApp = New Word.ApplicationClass()WordApp.Visible = TrueDimfileName = "Documento.docx"DimdocAsDocument = _WordApp.Documents.Open( _fileName:=fileName, ReadOnly:=True)VB
O que é compilado:ApplicationWordApp = (Application) Activator.CreateInstance(Type.GetTypeFromCLSID(newGuid("000209FF-0000-0000-C000-000000000046")));WordApp.Visible = true;stringfileName = "Documento.docx";object <>r__ComRefCallLocal0 = fileName;object <>r__ComRefCallLocal1 = false;object <>r__ComRefCallLocal2 = Type.Missing;object <>r__ComRefCallLocal3 = Type.Missing;object <>r__ComRefCallLocal4 = Type.Missing;object <>r__ComRefCallLocal5 = Type.Missing;object <>r__ComRefCallLocal6 = Type.Missing;object <>r__ComRefCallLocal7 = Type.Missing;object <>r__ComRefCallLocal8 = Type.Missing;object <>r__ComRefCallLocal9 = Type.Missing;object <>r__ComRefCallLocala = Type.Missing;object <>r__ComRefCallLocalb = Type.Missing;object <>r__ComRefCallLocalc = Type.Missing;object <>r__ComRefCallLocald = Type.Missing;object <>r__ComRefCallLocale = Type.Missing;object <>r__ComRefCallLocalf = Type.Missing;objectaDoc = WordApp.Documents.Open(ref <>r__ComRefCallLocal0,     ref <>r__ComRefCallLocal2, ref <>r__ComRefCallLocal1,     ref <>r__ComRefCallLocal3, ref <>r__ComRefCallLocal4,     ref <>r__ComRefCallLocal5, ref <>r__ComRefCallLocal6,     ref <>r__ComRefCallLocal7, ref <>r__ComRefCallLocal8,     ref <>r__ComRefCallLocal9,ref <>r__ComRefCallLocala,     ref <>r__ComRefCallLocalb, ref <>r__ComRefCallLocalc,     ref <>r__ComRefCallLocald, ref <>r__ComRefCallLocale,     ref <>r__ComRefCallLocalf);
Mesclando o assembly de interop
Com interop
Variância

C#4 – O que há de novo

  • 1.
    C#4 – Oque há de novoGiovanni Bassigiggio@giggio.nethttp://giovannibassi.comhttp://unplugged.giggio.net
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
    C#, VB, J#,F#, IronRuby, etc... (Beta a beta)
  • 7.
    Dezenas de artigosna .Net Magazine
  • 8.
    Editor técnico da.Net Magazine
  • 9.
  • 10.
  • 11.
    Líder e fundadordo .Net Architects (1º grupo de arquitetura de software com .Net do Brasil)
  • 12.
  • 13.
    Cerca de setemil mensagens desde sua criação
  • 14.
    Em torno demil mensagens por mês
  • 15.
    Cerca de 350membros online
  • 16.
  • 17.
  • 18.
  • 19.
    Efetivamente um dosmaiores e mais ativos grupos do país
  • 20.
    100 pessoas presentesno último (e primeiro) evento
  • 21.
    Próxima reunião em8 de Agosto, falando sobre OSLO com Waldemir Cambiucci (arquiteto Microsoft)Email: giggio@giggio.net
  • 22.
  • 23.
  • 24.
  • 25.
    .Net Architects: Grupo:http://dotnetarchitects.netPodcast: http://podcast.dotnetarchitects.netOnline: http://tinyurl.com/DotNetArchTwitter: #DotNetArchitectsOnline @
  • 26.
  • 27.
  • 28.
    FerramentalC# 4.0 (VisualC# 2010) está presente no Visual Studio 2010 Beta 1 lançado em MaioDownload do Beta tem apenas 1.3 GB, disponível em:http://tinyurl.com/vs10b1Também no VS10:VB XF#DLR (suporte para IronRuby, IronPython, etc...)
  • 29.
  • 30.
    C# e VBLadoa Lado com VBSem separação de perfil de desenvolvedor(Mas não espere XML Literals no C# )
  • 31.
    Quatro Grandes NovidadesConstruçõesdinâmicasArgumentos opcionais e argumentos nomeadosVariância para tipos genéricosMelhorias na interoperabilidade com o COM
  • 32.
  • 33.
    EsclarecendoArgumentos opcionaisPermite omitirargumentos na chamada de uma função, usando valores padrãoArgumentos nomeadosPermite dizer os nomes dos argumentos em uma chamada de funçãoIgualzinho há no VB.Net desde o .Net 1.0 e VB 7 (2002)
  • 34.
    VB (criando ométodo):PublicClass ElevadorPublicSub Subir( _OptionalByVal andares AsInteger = 1, _OptionalByVal velocidade AsInteger = 1)EndSubEndClass
  • 35.
    Chamada: como eraantes?var elevador = newElevador();elevador.Subir(1,1); //Obrigatório informar
  • 36.
    Chamada: como éagora?var elevador = newElevador();elevador.Subir();
  • 37.
    Declaração: como eraantes?publicclassElevadorCS {publicvoid Subir() {this.Subir(1, 1); }publicvoid Subir(int andares) {this.Subir(andares, 1); }publicvoid Subir(int andares, int velocidade) { } }
  • 38.
    Declaração: como éagora?publicclassElevadorCS {publicvoid Subir(int andares = 1, int velocidade = 1) { } }
  • 39.
    Vantagens e desvantagensVantagensMaisclaroMais explícitoMais simplesDesvantagensSe mal usado pode incentivar métodos com parâmetros demais
  • 40.
    RegrasParâmetros opcionais sãoos últimos do métodoSomente constantespublicvoid Subir(int andares = 1, int velocidade){}publicvoid Subir(int andares, int velocidade =ObterVelocidade()){}
  • 41.
  • 42.
    Como era antes?varelevador2 = newElevadorCS();elevador2.Subir(2, 3);
  • 43.
    Como é agora?varelevador2 = newElevadorCS();elevador2.Subir();elevador2.Subir(velocidade: 2);elevador2.Subir(velocidade: 2,andares: 3);
  • 44.
    RegrasVocê pode nomearqualquer argumento, seja ele opcional ou nãoArgumentos nomeados podem ser chamados em qualquer ordemAs chamadas são feitas na ordem em que são declaradas do chamador, e não na funçãopublicvoid Subir(int andares = 1, int velocidade = 1) {}elevador2.Subir( velocidade: this.ObterVelocidade(), andares: this.ObterAndares() );PrimeiroSegundo
  • 45.
  • 46.
  • 47.
    MotivaçãoMotivaçãoHype das linguagensdinâmicasProdutividadeTestesInteroperabilidadeExtensibilidade
  • 48.
    ExemploTeste com Cucumbere RSpec (IronRuby):Feature: Search courses In order to ensure better utilization of courses Potential students should be able to search for courses Scenario: Search by topic Given there are 240 courses which do not have the topic "biology" And there are 3 courses A,B,C that each have "biology" as one of the topics When I search for "biology" Then I should see the following courses: | title | | A | | B | | C |
  • 49.
    Entendendo a infraDynamicLanguageRuntime (DLR) agora é parte da BCLMicrosoft.CSharp é obrigatória para trabalhar com dynamicSomente no .Net 4.0
  • 50.
    Entendendo o dynamicTipossão “estáticamentetipados como dinâmicos”Tipos dinâmicos são System.Object’sTipos dinâmicos se propagam nas chamadasTipos dinâmicos não possuem checagem em tempo de compilação ou Intelisense
  • 51.
    Exemplosdynamic d;dynamic d1= 3;d1 = DateTime.Now;d.QualquerCoisa(3);Console.Writeline(d[10]);d.Propriedade1 = d.Propriedade2;d += 1;var a = d + Datetime.Now();d("algumparâmetro", 3);var d2 = d.AlgumValor();var d3 = ObterVariavelDinamica();
  • 52.
    Entendendo o StaticDispatchÉo comum até o C# 3.0Ligação forte com o método sendo chamadoSem perda de performance
  • 53.
    Entendendo o DynamicDispatchAresolução do método é feita em tempo de execuçãoSe for uma chamada sobre um tipo dinâmico (dynamicreceiver), a chamada é dinâmica (ligada em runtime)Se for uma chamada sobre um tipo e método estáticos (staticreceiver), mas houver um parâmetro dinâmico, também é uma chamada dinâmica (ligada em runtime)
  • 54.
    CuidadoO que aconteceaqui?staticintFuncao(int z) { return 1; }staticvoid Main(){dynamic x = 3;DateTime y = Funcao(x);}
  • 55.
    DynamicDispath != VirtualDispathSó pra constar, porque não vai dar tempo de explicarVejam uma discussão no .Net Architects:http://tinyurl.com/virtualdispatch
  • 56.
    Como o DLRencontra o métodoVerifica o cache de chamadas, se houver, utilizaSe o objeto for um IDynamicMetaObjectProvider, utiliza sua implementaçãoSe não for, utiliza o Binder do C#, no caso, com ReflectionSe não achar: RuntimeBinderException
  • 57.
    Resolução de sobrecargas(overloads)Mesma regra: se a chamada do método for dinâmica, o overload é avaliados somente em runtimeO DLR busca uma assinatura idêntica no cacheSe houver ele usa, senão ele busca uma converter os parâmetros, e achando, guarda no cacheSe não achar: RuntimeBinderException
  • 58.
  • 59.
    ExemplopublicclassConversor{publicvoid Converter(string x){ }publicvoid Converter(decimal x) { }}publicclassSuperConversor : Conversor{publicvoid Converter(int x) { }}
  • 60.
    PegadinhaQual sobrecarga échamada em cada caso?Conversor c1 = newSuperConversor();inti = 10;c1.Converter(i);Conversor c2 = newSuperConversor();dynamic d1 = 10;c2.Converter(d1);
  • 61.
    RespostapublicclassConversor{publicvoid Converter(string x){ }publicvoid Converter(decimal x) { }}publicclassSuperConversor : Conversor{publicvoid Converter(int x) { }}
  • 62.
    Regra 1A idéiaé replicar o comportamento estático, como se as chamadas não fossem dinâmicas
  • 63.
    Regra 2Dynamic éum Object. Cuidado com Boxing e Unboxing.dynamic d = new AlgumaClasse();d.s = default(S);d.s.i = 6;S é uma structi é um campo inteiro da structValendo mil reais…Qual o valor de i?
  • 64.
    Não funcionamMétodos deextensãoLINQ (depende de métodos de extensão)
  • 65.
  • 66.
  • 67.
    NovidadesNão precisamos maisda palavra-chave ref(o compilador coloca sozinho)Não precisamos de cast de tipos de valor para objectCom o suporte de parâmetros opcionais e nomeados, passamos só o necessárioIgualzinho ao que há no VB.Net desde o .Net 1.0 e VB 7 (2002)Temos ainda opção de mesclar o assembly de interop
  • 68.
    Como era antes?ApplicationClassWordApp= newApplicationClass();  WordApp.Visible = true;  objectmissing = System.Reflection.Missing.Value;  objectreadOnly = false;  objectfileName = "Documento.docx";  Word.Documentdoc = WordApp.Documents.Open(reffileName, refmissing, refreadOnly,refmissing, refmissing, refmissing,refmissing, refmissing, refmissing,refmissing, refmissing, refmissing,refmissing, refmissing, refmissing);
  • 69.
    Como é noVB?DimWordApp = New Word.ApplicationClass()WordApp.Visible = TrueDimfileName = "Documento.docx"DimdocAsDocument = _WordApp.Documents.Open( _fileName:=fileName, ReadOnly:=True)
  • 70.
    Como é agora?varWordApp= newApplicationClass();  WordApp.Visible = true;  stringfileName = "Documento.docx";  vardoc = WordApp.Documents.Open(fileName, ReadOnly:false);
  • 71.
    VB e C#lado a lado:varWordApp = newApplicationClass();  WordApp.Visible = true;  stringfileName = "Documento.docx";  vardoc = WordApp.Documents.Open(fileName, ReadOnly:false);C#DimWordApp = New Word.ApplicationClass()WordApp.Visible = TrueDimfileName = "Documento.docx"DimdocAsDocument = _WordApp.Documents.Open( _fileName:=fileName, ReadOnly:=True)VB
  • 72.
    O que écompilado:ApplicationWordApp = (Application) Activator.CreateInstance(Type.GetTypeFromCLSID(newGuid("000209FF-0000-0000-C000-000000000046")));WordApp.Visible = true;stringfileName = "Documento.docx";object <>r__ComRefCallLocal0 = fileName;object <>r__ComRefCallLocal1 = false;object <>r__ComRefCallLocal2 = Type.Missing;object <>r__ComRefCallLocal3 = Type.Missing;object <>r__ComRefCallLocal4 = Type.Missing;object <>r__ComRefCallLocal5 = Type.Missing;object <>r__ComRefCallLocal6 = Type.Missing;object <>r__ComRefCallLocal7 = Type.Missing;object <>r__ComRefCallLocal8 = Type.Missing;object <>r__ComRefCallLocal9 = Type.Missing;object <>r__ComRefCallLocala = Type.Missing;object <>r__ComRefCallLocalb = Type.Missing;object <>r__ComRefCallLocalc = Type.Missing;object <>r__ComRefCallLocald = Type.Missing;object <>r__ComRefCallLocale = Type.Missing;object <>r__ComRefCallLocalf = Type.Missing;objectaDoc = WordApp.Documents.Open(ref <>r__ComRefCallLocal0, ref <>r__ComRefCallLocal2, ref <>r__ComRefCallLocal1, ref <>r__ComRefCallLocal3, ref <>r__ComRefCallLocal4, ref <>r__ComRefCallLocal5, ref <>r__ComRefCallLocal6, ref <>r__ComRefCallLocal7, ref <>r__ComRefCallLocal8, ref <>r__ComRefCallLocal9,ref <>r__ComRefCallLocala, ref <>r__ComRefCallLocalb, ref <>r__ComRefCallLocalc, ref <>r__ComRefCallLocald, ref <>r__ComRefCallLocale, ref <>r__ComRefCallLocalf);
  • 73.
  • 74.
  • 75.