Partager via


Modifications importantes dans Visual C# 2010

Le tableau suivant répertorie les modifications importantes apportées à Visual C# 2010 qui peuvent empêcher la compilation d'une application créée avec Visual C# 2008 ou modifier son comportement au moment de l'exécution.

Catégorie

Problème

Description

Liaison d'assembly

La liaison d'assembly traite deux assemblys comme équivalents.

Les applications C# 2010 qui référencent simultanément la version du .NET Framework et la version du .NET Framework pour Silverlight d'un assembly de référence particulier, et qui utilisent extern alias, provoquent des erreurs du compilateur. Par défaut, la liaison d'assembly traite les deux assemblys comme étant équivalents.

Pour résoudre l'erreur, utilisez l'option de compilateur /appconfig pour spécifier l'emplacement d'un fichier app.config qui désactive le comportement par défaut à l'aide d'une balise <supportPortability>. Pour plus d'informations, consultez /appconfig (Options du compilateur C#).

Si vous générez une application à l'aide de Microsoft Build Engine (MSBuild), ajoutez la balise appropriée au fichier .csproj.

Covariance et contravariance

Une conversion implicite est ajoutée pour les interfaces génériques et les délégués tels que IEnumerable<T> et Func<TResult>.

Les interfaces génériques et les délégués tels que IEnumerable<T> et Func<TResult> ont désormais une conversion implicite pour les arguments de type générique. Par exemple, dans C# 2010, IEnumerable<string> peut être converti implicitement en IEnumerable<object>, ce qui peut provoquer un comportement différent dans les scénarios suivants.

Pour plus d'informations, consultez Covariance et contravariance (C# et Visual Basic).

Opérateur de fusion Null

L'opérateur de fusion Null (??) n'autorise pas les variables locales non assignées.

En C# 2010, vous ne pouvez pas utiliser de variables locales non assignées comme opérandes à droite de l'opérateur de fusion Null, même s'il est garanti que l'opérande de gauche n'a pas la valeur Null.

Par exemple, le code suivant compile en C# 2008, mais produit Erreur du compilateur CS0165 en C# 2010.

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

Inférence de type de groupe de méthode

Le compilateur peut déduire les délégués génériques et non génériques pour les groupes de méthode qui pourraient introduire de l'ambiguïté.

En C# 2008, le compilateur ne peut pas déduire les délégués génériques pour les groupes de méthode. Par conséquent, il utilise toujours un délégué non générique s'il existe.

En C# 2010, les délégués génériques et non génériques sont déduits pour les groupes de méthode et il est également probable que le compilateur déduise l'un ou l'autre. Cela peut entraîner de l'ambiguïté si vous avez des versions génériques et non génériques d'un délégué et que les deux répondent aux exigences. Par exemple, le code suivant compile en C# 2008 et appelle une méthode qui utilise un délégué non générique. En C# 2010, ce code génère une erreur de compilateur qui signale un appel ambigu.

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

Paramètres facultatifs

C# reconnaît désormais OptionalAttribute, ce qui peut provoquer des modifications dans la résolution de surcharge de méthode.

En C# 2008, le compilateur ignore OptionalAttribute, car C# ne prend pas en charge les paramètres facultatifs.

C# 2010 introduit des paramètres facultatifs. Vous pouvez déclarer des paramètres facultatifs à l'aide de la nouvelle syntaxe du langage ou à l'aide de OptionalAttribute. Si vous utilisez OptionalAttribute en C# 2008 pour l'interopérabilité avec d'autres langages qui prennent en charge des paramètres facultatifs (par exemple, Visual Basic), C# 2008 sélectionne toujours uniquement les méthodes qui ont tous les paramètres répertoriés dans l'appel de méthode. C# 2010 peut sélectionner une méthode comportant des paramètres facultatifs, même si ces paramètres ne sont pas spécifiés dans l'appel de méthode.

Le code suivant appelle une méthode d'une classe de base en C# 2008 parce qu'un attribut facultatif est ignoré et le compilateur se comporte comme si la méthode de la classe dérivée requiert toujours un paramètre de type. En C# 2010, le code appelle une méthode d'une classe dérivée parce que cette signature de méthode correspond maintenant à l'appel de méthode.

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

Pour plus d'informations, consultez Arguments nommés et facultatifs (Guide de programmation C#).

Types interop incorporés

La tentative de création d'une instance d'un type COM incorporé à l'aide de CoClass provoque une erreur du compilateur.

En C# 2010, lorsque vous ajoutez une référence à un assembly d'interopérabilité tel que Microsoft.Office.Interop.Word ou Microsoft.Office.Interop.Excel, les types de cet assembly sont incorporés. Pour plus d'informations, consultez Procédure pas à pas : incorporation de types provenant d'assemblys managés (C# et Visual Basic) et /link (Options du compilateur C#).

Lorsque vous créez une instance d'un type COM incorporé dans votre code, vous devez créer l'instance à l'aide de l'interface appropriée. Si vous essayez de créer une instance d'un type COM incorporé à l'aide de CoClass, le compilateur signale une erreur.

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

Types interop incorporés

Les propriétés indexées ne sont accessibles par get_ et les méthodes set_.

Lorsque vous incorporez des types COM, tous les appels aux objets COM sont distribués dynamiquement. Comme le montre l'exemple de code suivant, si vous essayez d'accéder à une propriété indexée Range à l'aide de la méthode get_Range, le classeur d'exécution C# recherche la méthode définie par l'utilisateur get_Range dans la classe, et cette méthode n'existe pas. Pour éviter ce problème, utilisez la syntaxe C# 2010 pour les propriétés indexées. Pour plus d'informations, consultez Comment : accéder aux objets Office Interop à l'aide des fonctionnalités Visual C# 2010 (Guide de programmation 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]];

Synchronisation d'événement

La synchronisation pour écrire dans le champ de stockage d'un événement dans les méthodes Add et Remove générées par le compilateur est désormais effectuée à l'aide de la méthode CompareExchange. Cela peut provoquer une condition de concurrence.

En C# 2010, la synchronisation pour modifier le champ de stockage pour les méthodes Add et Remove générées par le compilateur est effectuée à l'aide de la méthode CompareExchange au lieu de MethodImplAttribute.

Cela peut provoquer des conditions de concurrence qui n'étaient pas présentes dans C# 2008, comme illustré dans l'exemple de code suivant.

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

Pour éviter la condition de concurrence, modifiez la méthode Loop comme indiqué dans l'exemple de code suivant.

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

Voir aussi

Autres ressources

Mise en route de Visual C#

MSBuild