Freigeben über


Wichtige Visual C#-Änderungen in Visual Studio 2012

In der folgenden Tabelle sind Änderungen in Visual C# in Visual Studio 2012 auf, das möglicherweise entweder eine Anwendung verhindern, die in Visual C# in Visual Studio 2010 erstellte wurde oder das Laufzeitverhalten einer solchen Anwendung geändert hat.

Kategorie

Problem

Beschreibung

Lambda-Ausdrücke

Sie können die Iterationsvariable einer foreach-Anweisung in einem Lambda-Ausdruck verwenden, der im Text der Schleife enthalten ist.

Die Verwendung einer foreach Iterationsvariable in einem geschachtelten Lambda-Ausdruck stellt nicht mehr unerwartete Ergebnisse.Im folgenden Beispiel wird variable word in einem Lambda-Ausdruck.

static void Main()
{
    var methods = new List<Action>();
    foreach (var word in new string[] { "hello", "world" })
    {
        methods.Add(() => Console.Write(word + " "));
    }

    methods[0]();
    methods[1]();
}

// Output in Visual Studio 2012: 
// hello world

// Output in Visual Studio 2010: 
// world world

LINQ-Ausdrücke

Sie können die Iterationsvariable einer foreach-Anweisung in einem LINQ-Ausdruck verwenden, der im Text der Schleife enthalten ist.

Die Verwendung einer foreach Iterationsvariable in einem LINQ-Ausdruck stellt nicht mehr unerwartete Ergebnisse.Im folgenden Beispiel wird variable number in einer LINQ-Abfrage.

static void Main()
{
    var lines = new List<IEnumerable<string>>(); 
    int[] numbers = { 1, 2, 3 };
    char[] letters = { 'a', 'b', 'c' };

    foreach (var number in numbers)
    {
        var line = from letter in letters
                   select number.ToString() + letter;

        lines.Add(line);
    }

    foreach (var line in lines)
    {
        foreach (var entry in line)
            Console.Write(entry + " ");
        Console.WriteLine();
    }
}
// Output in Visual Studio 2012: 
// 1a 1b 1c
// 2a 2b 2c
// 3a 3b 3c

// Output in Visual Studio 2010: 
// 3a 3b 3c
// 3a 3b 3c
// 3a 3b 3c

Benannte Argumente

Nebeneffekte von mit dem Namen und Positionsargumente in einem Methodenaufruf treten jetzt von links nach rechts in der Argumentliste auf.

Nebeneffekte von mit dem Namen und Positionsargumente, die in einem Methodenaufruf kombiniert werden, werden jetzt von links nach rechts in der angegebene Argumentliste der Anweisung erzeugt.Im folgenden Beispiel wird TestMethod aufgerufen, indem Sie eine Kombination von mit dem Namen und Positionsargumente in verschiedenen Bestellungen verwendet.

class Program
{
    static void Main(string[] args)
    {
        TestMethod(WriteLetter("A"), b: WriteLetter("B"), c: WriteLetter("C"));
        TestMethod(WriteLetter("A"), c: WriteLetter("C"), b: WriteLetter("B"));
    }

    static int WriteLetter(string letter)
    {
        Console.Write(letter + " ");
        return 1;
    }

    static void TestMethod(int a, int b, int c)
    { }

    // Output in Visual Studio 2012:
    // A B C A C B

    // Output in Visual Studio 2010:
    // B C A C B A
}

Überladungsauflösung

Überladungsauflösung ist für Aufrufe verbessert, die benannte Argumente auf Methoden verwenden, die Parameter-Parameter enthalten.

Wenn mehr als ein Auflösungskandidat gefunden wird, bevorzugt Überladungsauflösung die spezifischste Typabgleichung für benannte Argumente.Parameter, für die Argumente nicht erforderlich oder im Aufruf bereitgestellt sind, werden berücksichtigt, wenn die Typabgleichungen in den Überladungskandidaten gleichwertig sind.

Im folgenden Beispiel ist string ein besserer Typ als object für p2.Daher soll die Version von ExampleMethod, in der Parameter p2 als Zeichenfolge definiert ist, ausgewählt werden, obwohl sie über einen dritten params-Parameter verfügt.

class Program
{
    static void Main(string[] args)
    {
        ExampleMethod(p2: "");
    }

    public static void ExampleMethod(string p1 = null, object p2 = null)
    {
        Console.WriteLine("ExampleMethod: p2 is object");
    }
    public static void ExampleMethod(string p2 = null, object p1 = null, params int[] p3)
    {
        Console.WriteLine("ExampleMethod: p2 is string");
    }
}

// Output in Visual Studio 2012:
// ExampleMethod: p2 is string

// Output in Visual Studio 2010:
// ExampleMethod: p2 is object

Überladungsauflösung

Überladungsauflösung wird für Aufrufe verbessert, in denen der Algorithmus zwischen einem Func<object>-Parameter und einen Func-Parameter auswählen muss, der einen anderen Typparameter (z. string, oder int?) für ein Func<dynamic>-Argument verfügt.

Im folgenden Beispiel verfügt der Aufruf CandidateMethod, der sendet, ein Func<dynamic>-Argument zwei Auflösungskandidaten.Der entsprechende Parameter in einem der Kandidaten ist Func<object>, und der entsprechende Parameter im anderen ist Func<string>.

Der Überladungskandidat, der einen Func<object>-Parameter verfügt, muss ausgewählt werden, da object und dynamic als gleich betrachtet werden.Daher existiert eine Identitätskonvertierung nicht nur zwischen dynamic und object jedoch auch zwischen konstruierten Typen Func<dynamic> und Func<object>.

class Program
{
    public static void CandidateMethod(Func<object> fun)
    {
        Console.WriteLine("Method that has a Func<object> parameter.");
    }

    public static void CandidateMethod(Func<string> fun)
    {
        Console.WriteLine("Method that has a Func<string> parameter.");
    }

    static void Main(string[] args)
    {
        dynamic dyn = 15;
        CandidateMethod(() => { return dyn; });
    }
}
// Output in Visual Studio 2012:
// Method that has a Func<object> parameter.

// Output in Visual Studio 2010 if Microsoft.CSharp is referenced:
// Method that has a Func<string> parameter.

// Output in Visual Studio 2010 if Microsoft.CSharp isn't referenced (for instance, in a Unit Test Project):
// Method that has a Func<object> parameter.

Siehe auch

Referenz

Lambda-Ausdrücke (C#-Programmierhandbuch)

params (C#-Referenz)

dynamic (C#-Referenz)

Konzepte

Benannte und optionale Argumente (C#-Programmierhandbuch)

Weitere Ressourcen

Erste Schritte mit Visual C#

Wann unterbricht geschützter Sprachenfix?