2017-10-06 49 views
3

我想ValueTuple類在C#中,我有一個關於性命名疑問,讓我們來看看:C#ValueTuple性質命名

如果實例化一個ValueTuple宣佈這樣的對象:var tuple1 = (Name: "Name1", Age: 25); 我們可以命名的屬性,

但是,像這樣的:ValueTuple<string,int> tuple2 = (Name: "Name1", Age: 25);

,我們得到的是說,名稱將被忽略警告,所以

我們應該輸入:ValueTuple<string,int> tuple2 = ("Name1",25);

那麼屬性將tuple2.Item1tuple2.Item2

有人能解釋這個新手這個原因嗎?

比你的優勢

+0

'ValueTuple'只是一個普通的C#類型,沒有編譯器的特別支持。它的成員總是被稱爲'Item1','Item2'等等。然而,'(x,y)'元組語法在編譯器的特別支持下爲元組成員引入了其他名稱,並將它們映射到生成的IL代碼中適當的'ValueType'名稱。 –

+0

「但是,像這樣:'ValueTuple tuple2 =(Name:」Name1「,Age:25);' 我們收到一個錯誤」 - 不,而不是你已經顯示的代碼。您會收到警告,指出元組文字中的名稱被有效忽略,但您不會收到錯誤。 –

回答

12

這裏涉及的元組的兩個不同的「種」:在.NET ValueTuple<...>類型和C#的元組類型。 C#元組類型可以有元素名稱; ValueTuple<...>類型不能。 (在類型系統中根本就沒有任何地方可以正常生活)

在執行時,一個值只知道它的.NET類型。例如,如果你使用:

(string x, int y) tuple1 = ("hello", 10); 
(string a, int b) tuple2 = ("hello", 10); 
DoSomethingWithValue(tuple1); 
DoSomethingWithValue(tuple2); 
... 
void DoSomethingWithValue(object value) { ... } 

然後DoSomethingWithValue將不能夠在所有的二元組值來區分。該信息僅在編譯時可用。

有關參數和返回類型等元素名稱的信息將通過C#編譯器使用的屬性傳播。因此,例如,一個方法聲明如下:

public (string name, int score) GetFoo() 

在IL被編譯,如果它已被宣佈這樣的:

[TupleElementNames(new string[] { "name", "score" }] 
public ValueTuple<string, int> GetFoo() 

C#語言定義.NET類型和之間的適當的轉換C#元組類型使其儘可能無縫。

就如何使用元組而言,儘可能使用C#元組類型。命名元組元素在可用性方面有很大的不同。

+3

謝謝Jon,這幫助我理解了發生了什麼,並且[this](http://josephwoodward.co.uk/2017/04/csharp-7-valuetuple-types-and-their-limitations) C#7段也有所幫助 – Ferus7

0

要定義什麼是

(string Name,int Age) tuple1 = (Name: "Name1", Age: 25); 

要定義什麼是

ValueTuple<string,int> tuple2 = (Name: "Name1", Age: 25); 

只看該類型要定義之間的差異。如果你拿這個名字,兩者都是兩回事。

+2

根本沒有回答這個問題 - 在這兩種情況下,基礎類型都是「ValueTuple」(同樣,所使用的「var」示例OP與您的第一個示例相同) – UnholySheep

+0

OP想知道它們爲什麼不同。這是我在這裏給出的,因爲兩者都是不同的類型。 –

+2

他們不是不同的類型。嘗試你的代碼並添加'Console.WriteLine(tuple1.GetType()。FullName);''和'Console.WriteLine(tuple2.GetType()。FullName);' –