Udostępnij za pośrednictwem


Visual C# — przełomowe zmiany w Visual Studio 2012

W poniższej tabeli wymieniono zmiany w środowisku Visual C# w Visual Studio 2012 , który może uniemożliwić aplikacji, która została utworzona w Visual C# w Visual Studio 2010 kompilacji albo zmień zachowaniem takiej aplikacji w czasie wykonywania.

Kategoria

Problem

Opis

Wyrażenia lambda

Można użyć zmiennej iteracji z foreach instrukcja w wyrażenie lambda, zawarte w treści pętli.

Użycie foreach Zmienna iteracji w wyrażeniu lambda zagnieżdżone nie są już nie daje oczekiwanych wyników.W poniższym przykładzie użyto zmiennej word w wyrażeniu lambda.

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

Wyrażenia LINQ

Można użyć zmiennej iteracji z foreach instrukcji w wyrażeniu LINQ, zawarte w treści pętli.

Użycie foreach Zmienna iteracji w wyrażeniu LINQ nie daje oczekiwanych wyników.W poniższym przykładzie użyto zmiennej number w kwerendzie LINQ.

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

Nazwanych argumentów

Skutków ubocznych argumenty nazwane i pozycyjne w wywołaniu metody teraz wystąpić od lewej do prawej, na liście argumentów.

Skutków ubocznych argumenty nazwane i pozycyjne, które są łączone w wywołaniu metody są obecnie produkowana od lewej do prawej w wywołujący instrukcja listy argumentów.W poniższym przykładzie TestMethod nazywa się przy użyciu kombinacji argumentów nazwanych i pozycyjne w różnej kolejności.

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
}

Przeciążenia

Ulepszono wiązaniem dla rozmowy z wykorzystaniem nazwanych argumentów do metody dostępu, które zawierają params parametry.

W przypadku stwierdzenia więcej niż jednego kandydata rozdzielczość, wiązaniem woli najdokładniej pasuje typu dla nazwanych argumentów.Parametry, dla których argumenty nie są wymagane lub dostarczone do wywołania są uważane za tylko wtedy, kiedy są równie dobre dopasowania typu w przeciążenie kandydatów.

W poniższym przykładzie string typu lepiej niż object dla p2.W związku z tym, wersja ExampleMethod w parametr, który p2 jest zdefiniowany jako ciąg powinien zostać wybrany, mimo że ma trzeciego params parametru.

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

Przeciążenia

Ulepszone wiązaniem dla wywołań, gdzie algorytm musi wybierać między Func<object> parametr i Func parametr, który ma parametr innego typu (np. string lub int?) dla Func<dynamic> argument.

W poniższym przykładzie wywołanie CandidateMethod , który wysyła Func<dynamic> argumentu po dwóch kandydatów, którzy rozdzielczość.Odpowiadającego mu parametru w jednym z kandydatów jest Func<object>, i odpowiadającego mu parametru w innych jest Func<string>.

Kandydat przeciążenie, który ma Func<object> powinien zostać wybrany parametr, ponieważ object i dynamic są uważane za równoważne.W związku z tym, konwersję tożsamości istnieje nie tylko między dynamic i object , ale również między typami konstruowanej Func<dynamic> i 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.

Zobacz też

Informacje

Wyrażenia lambda (Podręcznik programowania C#)

params (C# odniesienia)

dynamiczne (C# odniesienia)

Koncepcje

Argumenty nazwane i opcjonalne (Podręcznik programowania C#)

Inne zasoby

Wprowadzenie do programu Visual C#

Kiedy łamie poprawka języka twardej?