Alterações significativas Visual C# 2010

A tabela a seguir lista as alterações significativas feitas no Visual 2010 C# que podem impedir que um aplicativo que foi criado no Visual C# 2008 compilação ou que pode alterar o seu comportamento de tempo de execução.

<strong>Categoria</strong>

Assunto

Descrição

Ligação de assembly

Ligação de assembly trata os dois assemblies como equivalente.

Aplicativos C# 2010 que fazem referência a ambos os.NET Framework versão e o.NET Framework para a versão do Silverlight de um conjunto específico de referência ao mesmo tempo e que também uso extern alias, causar erros de compilador. Por padrão, o vinculação de assembly trata os dois assemblies como equivalente.

Para resolver o erro, use o /appconfig opção de compilador para especificar o local de um arquivo app. config que desativa o comportamento padrão usando um <supportPortability> marca. Para obter mais informações, consulte /AppConfig ( Opçõesdo compilador de C#).

Se você estiver criando um aplicativo usando o Microsoft Build Engine (MSBuild), adicione a marca correta para o arquivo. csproj.

Covariância e/contravariância

Uma conversão implícita de nova é adicionada para interfaces genéricas e delega como IEnumerable<T> e Func<TResult>.

Genérico, interfaces e delega como IEnumerable<T> e Func<TResult> agora tem uma conversão implícita para argumentos de tipo genérico. Por exemplo, em 2010 C# IEnumerable<string> pode ser convertido implicitamente em IEnumerable<object>, que pode causar um comportamento diferente a cenários a seguir.

Para obter mais informações, consulte Covariância e/contravariância (C# e Visual Basic).

Operador de concentração de NULL

O operador de concentração de null (??) não permite que as variáveis de local não atribuído.

C# 2010, é possível usar variáveis de locais não atribuídas como operandos no lado direito do operador concentração de null, mesmo se o operando no lado esquerdo é garantido que não pode ser nulo.

Por exemplo, o código a seguir compila e C# de 2008, mas produz Compiler Error CS0165 C# 2010.

int? i;
int? j;
int? x = (i = 2) ?? j;

Inferência de tipo de grupo de método

O compilador pode inferir representantes genéricos e não genéricas para os grupos de método, podem introduzir a ambigüidade.

C# de 2008, o compilador não é possível inferir representantes genéricos para os grupos de método. Portanto, sempre ele usa um delegado não genéricas se houver.

C# 2010, representantes genéricos e não genéricas são inferidos para grupos de método e o compilador é igualmente provável inferir um. Se você tiver versões genéricas e não genérica de um delegado e ambos satisfazem os requisitos, isso pode gerar ambigüidade. Por exemplo, o código a seguir é compatível em C# de 2008 e chama um método que usa um delegado não genéricas. C# 2010, esse código produz um erro do compilador reporta uma chamada ambígua.

public class Sample
{
    delegate string NonGenericDelegate();
    delegate T GenericDelegate<T>();
    string UseDelegate(NonGenericDelegate del)
    {
        return null;
    }

    T UseDelegate<T>(GenericDelegate<T> del)
    {
       return default(T);
    }

    public string Test()
    {
       // This line produces 
       // a compiler error in C# 2010.
       return UseDelegate(Test);
    }
}

Parâmetros opcionais

C# agora reconhece OptionalAttribute, que pode causar alterações na resolução de sobrecarga de método.

C# de 2008, o compilador ignora OptionalAttribute porque C# não suporta parâmetros opcionais.

C# 2010 introduz parâmetros opcionais. Você pode declarar parâmetros opcionais usando a nova sintaxe de linguagem ou usando OptionalAttribute. Se você usar OptionalAttribute C# 2008 para interoperabilidade com outras linguagens que suportam parâmetros opcionais (por exemplo, Visual Basic) C# 2008 sempre escolhe apenas os métodos que possuem todos os parâmetros listados na chamada de método. C# 2010 pode escolher um método de parâmetros opcionais, mesmo se esses parâmetros não forem especificados na chamada do método.

O código a seguir chama um método de uma classe base C# 2008 porque um atributo opcional será ignorado e o compilador se comporta como se o método na classe derivada sempre requer um parâmetro de seqüência de caracteres. C# 2010, o código chama um método de classe derivada, porque a assinatura do método agora coincide com a chamada de método.

class Program
{
    public static void Main(string[] args)
    {
        var obj = new Derived();
        obj.Method();
    }
}

class Base
{
    public void Method() 
    { 
        Console.WriteLine(
            "Base class + no optional parameters"); 
    }
}

class Derived : Base
{
    public void Method(
        [Optional][DefaultParameterValue("Hello")] 
        string s) 
    { 
        Console.WriteLine(
            "Derived class + an optional parameter");
    }
}
// Prints different results.
// C# 2008: Base class + no optional parameters
// C# 2010: Derived class + an optional parameter

Para obter mais informações, consulte Nome e argumentos Opcional (guia de programação de C#).

Tipos de interoperabilidade incorporados

A tentativa de criar uma instância de um tipo de incorporado COM usando CoClass causa um erro do compilador.

C# 2010, quando você adiciona uma referência a um assembly de interoperabilidade, como Microsoft.Office.Interop.Word ou Microsoft.Office.Interop.Excel, os tipos a partir deste assembly são incorporados. Para obter mais informações, consulte Demonstra Passo a passo: Tipos de incorporação de Assemblies gerenciados (C# e Visual Basic) e /link ( Opçõesdo compilador de C#).

Quando você cria uma instância do tipo COM incorporado no seu código, você deve criar a instância usando a interface apropriada. Se você tentar criar uma instância do tipo COM incorporado usando o CoClass, o compilador reporta um erro.

// Add the following statement
// at the beginning of the file:
// using Word = Microsoft.Office.Interop.Word;
// This statement does not compile in C# 2010.
Word.Application wordClass = 
    new Word.ApplicationClass();
// Use the following code instead.
Word.Application wordInterface = 
    new Word.Application();

Tipos de interoperabilidade incorporados

Propriedades indexadas não podem ser acessadas por get_ e set_ métodos.

Ao incorporar tipos COM, todas as chamadas para objetos COM são expedidas dinamicamente. Conforme mostrado no exemplo de código a seguir, se você tentar acessar uma propriedade indexada Range usando o get_Range método, o fichário de tempo de execução C# procura definido pelo usuário get_Range método na classe e esse método não existe. Para evitar esse problema, use a sintaxe C# 2010 para propriedades indexadas. Para obter mais informações, consulte How to: Objetos de interoperabilidade do Office Access usando recursos visuais C# 2010 (guia de programação C#).

// Add the following statement
// at the beginning of the file:
// using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excelApp = new Excel.Application();
excelApp.Visible = true;
excelApp.Workbooks.Add(
    Excel.XlWBATemplate.xlWBATWorksheet);
Excel.Worksheet sheet = 
    excelApp.ActiveSheet as Excel.Worksheet;
// The following statement throws 
// a run-time excpetion in C# 2010.
Excel.Range rangeOld = 
    sheet.get_Range(
        sheet.Cells[1, 1], sheet.Cells[2, 2]);
// Use the following syntax instead.
Excel.Range rangeNew = 
    sheet.Range[sheet.Cells[1, 1], 
                sheet.Cells[2, 2]];

Sincronização de evento

Agora, a sincronização para gravar em campo, fazendo do evento nos gerado pelo compilador adicionar e remover métodos é obtida usando o CompareExchange método. Isso pode causar uma condição de corrida.

C# 2010, a sincronização para alterar o campo de apoio para o gerado pelo compilador adicionar e remover métodos é obtida usando o CompareExchange método em vez de MethodImplAttribute.

Isso pode causar condições de corrida que não estavam presentes em C# de 2008, conforme mostrado no exemplo de código a seguir.

using System;
using System.Threading;

class Sample
{
    public event Action sampleEvent;

    static void Main()
    {
        new Sample().Loop();
    }

    void Loop()
    {
        new Thread(() => Test.Method(this)).Start();
        while (true)
        {
            lock (this)
            {
                if (sampleEvent != null)
                {
                    // In C# 2010, sampleEvent 
                    // can be null here,
                    // which causes 
                    // a run-time exception.
                    sampleEvent();
                }
            }
        }
    }
}

class Test
{
    public static void Method(Sample arg)
    {
        while (true)
        {
            arg.sampleEvent += Method;
            arg.sampleEvent -= Method;
        }
    }
    static void Method() { }
}

Para evitar a condição de corrida, modifique o Loop método conforme mostrado no seguinte exemplo de código.

void Loop()
{
   new Thread(() => Test.Method(this)).Start();
   while (true)
   {
       lock (this)
       {
           // Create a local copy of the delegate.
           Action local = sampleEvent;
           if (local != null)
           {
               local();
           }
        }
    }
}

Consulte também

Outros recursos

Getting Started with Visual C#

MSBuild