共用方式為


Visual Studio 2012 中 Visual C# 的重大變更

下表列出在 Visual C# 中的變更可能是防止應用程式在 Visual Studio 2010 的 Visual C# 建立從編譯或變更這類應用程式的執行階段行為的 Visual Studio 2012 。

分類

問題

描述

Lambda 運算式

您可以在迴圈主體包含 Lambda 運算式可以使用 foreach 陳述式中的反覆運算變數。

用於巢狀 Lambda 運算式的 foreach 反覆運算變數不再產生未預期的結果。下列範例在 Lambda 運算式中使用變數的 word 。

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 運算式

您可以在迴圈主體中的 LINQ 運算式可以使用 foreach 陳述式中的反覆運算變數。

使用 LINQ 運算式的 foreach 反覆運算變數不再產生未預期的結果。下列範例在 LINQ 查詢中使用變數的 number 。

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

具名引數

從名為的副作用和位於這個位置引數在引數清單由左至右立即發生。

在方法呼叫會將具名引數和位置引數的副作用在呼叫陳述式的引數清單由左至右現在會導致。使用具名的組合和位置引數不同的命令,如下列範例所示,呼叫 TestMethod 。

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
}

多載解析

多載解析為使用 具名引數 存取方法包含 param 參數的呼叫已改善。

當多個對話方塊的名稱解析候選,多載解析慣用具名引數的最特定的型別相符。引數會呼叫並不需要或不提供的參數會考慮,只有在多載候選的型別符合同樣都時。

在下列範例中, string 與 p2的 object 會是較佳的型別。因此,參數 p2 會定義 ExampleMethod 的版本,並應該選取字串,,即使有三個 params 參數。

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

多載解析

多載解析為演算法必須在 Func<object> 參數和 Func 參數之間具有 Variant 型別參數的呼叫改進 (也就是說, string 或 int?) Func<dynamic> 引數的。

在下列範例中,傳送對 CandidateMethod 的呼叫 Func<dynamic> 引數具有兩個名稱解析候選。對應參數的其中一個候選中,則為 Func<object>,並在其他的對應的參數為 Func<string>。

具有 Func<object> 參數的多載候選應該,因為 object 和 dynamic 被視為是相等。因此,識別轉換存在不僅在 dynamic 和 object ,而且在建構型別 Func<dynamic> 和 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.

請參閱

參考

Lambda 運算式 (C# 程式設計手冊)

params (C# 參考)

dynamic (C# 參考)

概念

具名和選擇性引數 (C# 程式設計手冊)

其他資源

Visual C# 使用者入門

非中斷語言內建何時中斷?