Demet türleri (C# Başvurusu)
C# 7,0 ve üzeri sürümlerde, Tanımlama grupları özelliği basit bir veri yapısındaki birden çok veri öğesini gruplamak için kısa bir sözdizimi sağlar. Aşağıdaki örnek, bir tanımlama grubu değişkeni bildirme, bunu başlatma ve veri üyelerine erişme işlemlerinin nasıl yapılacağını gösterir:
(double, int) t1 = (4.5, 3);
Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}.");
// Output:
// Tuple with elements 4.5 and 3.
(double Sum, int Count) t2 = (4.5, 3);
Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
// Output:
// Sum of 3 elements is 4.5.
Yukarıdaki örnekte gösterildiği gibi, bir demet türü tanımlamak için, tüm veri üyelerinin ve isteğe bağlı olarak alan adlarınıntürlerini belirtirsiniz. Tanımlama grubu türünde Yöntemler tanımlayamazsınız, ancak aşağıdaki örnekte gösterildiği gibi .NET tarafından sunulan yöntemleri kullanabilirsiniz:
(double, int) t = (4.5, 3);
Console.WriteLine(t.ToString());
Console.WriteLine($"Hash code of {t} is {t.GetHashCode()}.");
// Output:
// (4.5, 3)
// Hash code of (4.5, 3) is 718460086.
C# 7,3 ' den başlayarak demet türleri eşitlik işleçlerini == ve ' ı destekler != . Daha fazla bilgi için demet eşitlik bölümüne bakın.
Demet türleri değer türleridir; demet öğeleri ortak alanlardır. Bu, başlıkların değişebilir değer türlerini yapar.
Not
tanımlama grupları özelliği, System.ValueTuple System.ValueTuple<T1,T2> .net Core ve .NET Framework 4,7 ve üzeri sürümlerde bulunan tür ve ilgili genel türleri (örneğin,) gerektirir. .NET Framework 4.6.2 veya daha önceki bir sürümünü hedefleyen bir projede tanımlama gruplarını kullanmak için, NuGet paketini System.ValueTuple projeye ekleyin.
Tanımlama gruplarını rastgele çok sayıda öğe ile tanımlayabilirsiniz:
var t =
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26);
Console.WriteLine(t.Item26); // output: 26
Tanımlama gruplarının kullanım durumları
Tanımlama gruplarının en yaygın kullanım çalışmalarından biri yöntem dönüş türü olarak kullanılır. Diğer bir deyişle, out Yöntem parametreleritanımlamak yerine, aşağıdaki örnekte gösterildiği gibi, yöntemi, kayıt kümesi dönüş türü olarak gruplandırabilirsiniz.
var xs = new[] { 4, 7, 9 };
var limits = FindMinMax(xs);
Console.WriteLine($"Limits of [{string.Join(" ", xs)}] are {limits.min} and {limits.max}");
// Output:
// Limits of [4 7 9] are 4 and 9
var ys = new[] { -9, 0, 67, 100 };
var (minimum, maximum) = FindMinMax(ys);
Console.WriteLine($"Limits of [{string.Join(" ", ys)}] are {minimum} and {maximum}");
// Output:
// Limits of [-9 0 67 100] are -9 and 100
(int min, int max) FindMinMax(int[] input)
{
if (input is null || input.Length == 0)
{
throw new ArgumentException("Cannot find minimum and maximum of a null or empty array.");
}
var min = int.MaxValue;
var max = int.MinValue;
foreach (var i in input)
{
if (i < min)
{
min = i;
}
if (i > max)
{
max = i;
}
}
return (min, max);
}
Yukarıdaki örnekte gösterildiği gibi, döndürülen demet örneğiyle doğrudan çalışabilir veya ayrı değişkenlerde oluşturabilirsiniz.
Anonim türleryerine demet türlerini de kullanabilirsiniz; Örneğin, LINQ sorgularında. Daha fazla bilgi için bkz. anonim ve demet türleri arasında seçim yapma.
Genellikle, gevşek ilgili veri öğelerini gruplamak için tanımlama gruplarını kullanırsınız. Bu, genellikle özel ve iç yardımcı program yöntemlerinde yararlı olur. Ortak API söz konusu olduğunda, bir sınıf veya Yapı türü tanımlamayı düşünün.
Demet alan adları
Aşağıdaki örnekte gösterildiği gibi demet başlatma ifadesinde veya bir demet türü tanımında kayıt kümesi alanlarının adlarını açıkça belirtebilirsiniz:
var t = (Sum: 4.5, Count: 3);
Console.WriteLine($"Sum of {t.Count} elements is {t.Sum}.");
(double Sum, int Count) d = (4.5, 3);
Console.WriteLine($"Sum of {d.Count} elements is {d.Sum}.");
C# 7,1 ile başlayarak, bir alan adı belirtmezseniz, aşağıdaki örnekte gösterildiği gibi, bir demet başlatma ifadesinde karşılık gelen değişkenin adından çıkarsanolabilir:
var sum = 4.5;
var count = 3;
var t = (sum, count);
Console.WriteLine($"Sum of {t.count} elements is {t.sum}.");
Bu, demet projeksiyon başlatıcıları olarak bilinir. Bir değişkenin adı, aşağıdaki durumlarda bir demet alan adı üzerine yansıtılmıyor:
- Aday adı, örneğin,, veya gibi bir tanımlama grubu türünün üye adıdır
Item3ToStringRest. - Aday adı, başka bir tanımlama grubu alan adının veya açık ya da örtük bir yinelemesidir.
Bu durumlarda, bir alanın adını açıkça belirtirsiniz ya da bir alana varsayılan adıyla erişebilirsiniz.
Demet alanlarının varsayılan adları Item1 ,, vb. ' dir Item2 Item3 . Aşağıdaki örnekte gösterildiği gibi, bir alan adı açıkça veya çıkarsansa bile, bir alanın varsayılan adını her zaman kullanabilirsiniz:
var a = 1;
var t = (a, b: 2, 3);
Console.WriteLine($"The 1st element is {t.Item1} (same as {t.a}).");
Console.WriteLine($"The 2nd element is {t.Item2} (same as {t.b}).");
Console.WriteLine($"The 3rd element is {t.Item3}.");
// Output:
// The 1st element is 1 (same as 1).
// The 2nd element is 2 (same as 2).
// The 3rd element is 3.
Demet atama ve tanımlama grubu eşitlik karşılaştırmaları , alan adlarını hesaba almaz.
Derleme zamanında, derleyici varsayılan olmayan alan adlarını karşılık gelen varsayılan adlarla değiştirir. Sonuç olarak, açıkça belirtilen veya Çıkarsanan alan adları çalışma zamanında kullanılamaz.
Demet atama ve ayrıştırma
C#, aşağıdaki koşulların her ikisini de karşılayan demet türleri arasında atamayı destekler:
- Her iki demet türü de aynı sayıda öğe içermelidir
- her demet konumu için, sağ taraftaki demet öğesinin türü, karşılık gelen sol taraftaki demet öğesinin türüne göre veya örtülü olarak dönüştürülebilir
Demet öğesi değerleri demet öğelerinin sırasına göre atanır. Aşağıdaki örnekte gösterildiği gibi, demet alanlarının adları yoksayılır ve atanmaz:
(int, double) t1 = (17, 3.14);
(double First, double Second) t2 = (0.0, 1.0);
t2 = t1;
Console.WriteLine($"{nameof(t2)}: {t2.First} and {t2.Second}");
// Output:
// t2: 17 and 3.14
(double A, double B) t3 = (2.0, 3.0);
t3 = t2;
Console.WriteLine($"{nameof(t3)}: {t3.A} and {t3.B}");
// Output:
// t3: 17 and 3.14
Ayrıca, = farklı değişkenlerde bir demet örneğini bırakmak için atama işlecini de kullanabilirsiniz. Bunu aşağıdaki yöntemlerle yapabilirsiniz:
Her değişkenin türünü parantez içinde açıkça bildirin:
var t = ("post office", 3.6); (string destination, double distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers.varÖrtük olarak yazılmış değişkenleri bildirmek ve derleyicinin türlerini saymasına izin vermek için parantez dışında anahtar sözcüğünü kullanın:var t = ("post office", 3.6); var (destination, distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers.Mevcut değişkenleri kullan:
var destination = string.Empty; var distance = 0.0; var t = ("post office", 3.6); (destination, distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers.
Başlıkların ve diğer türlerin çıkarılması hakkında daha fazla bilgi için bkz. tanımlama gruplarını ve diğer türleri kaldırma.
Tanımlama grubu eşitliği
C# 7,3 ' den başlayarak demet türleri == ve işleçlerini destekler != . Bu işleçler, sol işlenenin üyelerini, demet öğelerinin sırası takip eden sağ işlenenin ilgili üyeleriyle karşılaştırın.
(int a, byte b) left = (5, 10);
(long a, int b) right = (5, 10);
Console.WriteLine(left == right); // output: True
Console.WriteLine(left != right); // output: False
var t1 = (A: 5, B: 10);
var t2 = (B: 5, A: 10);
Console.WriteLine(t1 == t2); // output: True
Console.WriteLine(t1 != t2); // output: False
Yukarıdaki örnekte gösterildiği gibi, == ve işlemleri de != Hesap tanımlama grubu alan adlarını almaz.
İki tanımlama grubu, aşağıdaki koşulların her ikisi de karşılanmadığı zaman karşılaştırılabilir:
- Her iki tanımlama grubu aynı sayıda öğe içerir. Örneğin,
t1 != t2t1vet2farklı sayıda öğe varsa derleme yapmaz. - Her demet konumu için, sol taraftaki ve sağ taraftaki demet işlenenlerinden karşılık gelen öğeler
==ve!=işleçleriyle karşılaştırılabilir. Örneğin,(1, (2, 3)) == ((1, 2), 3)ile karşılaştırılabilir olmadığı için derleme yapmaz1(1, 2).
==Ve != işleçleri, tanımlama gruplarını kısa devre bir şekilde karşılaştırın. Diğer bir deyişle, bir işlem eşit olmayan bir öğe çifti karşıladığında veya tanımlama gruplarının uçlarına ulaştığında duraklar. Ancak, herhangi bir karşılaştırmaya başlamadan önce, aşağıdaki örnekte gösterildiği gibi Tüm demet öğeleri değerlendirilir:
Console.WriteLine((Display(1), Display(2)) == (Display(3), Display(4)));
int Display(int s)
{
Console.WriteLine(s);
return s;
}
// Output:
// 1
// 2
// 3
// 4
// False
Out parametreleri olarak tanımlama grubu
Genellikle, out parametreleri olan bir yöntemi, bir tanımlama grubu döndüren bir yönteme yeniden düzenlemelisiniz. Ancak, bir out parametrenin demet türünde olabilecek durumlar vardır. Aşağıdaki örnek, tanımlama grupları ile parametre olarak nasıl çalışalınacağını gösterir out :
var limitsLookup = new Dictionary<int, (int Min, int Max)>()
{
[2] = (4, 10),
[4] = (10, 20),
[6] = (0, 23)
};
if (limitsLookup.TryGetValue(4, out (int Min, int Max) limits))
{
Console.WriteLine($"Found limits: min is {limits.Min}, max is {limits.Max}");
}
// Output:
// Found limits: min is 10, max is 20
Ve başlıkları System.Tuple
Türlerine göre desteklenen C# tanımlama grupları System.ValueTuple , türlerle temsil edilen tanımlama tiplerinden farklıdır System.Tuple . Ana farklılıklar aşağıdaki gibidir:
ValueTupletürler değer türlerdir.Tupletürler başvuru türleridir.ValueTupletürler değişebilir.Tupletürler sabittir.- Türlerin veri üyeleri
ValueTuplealanlardır. Türlerin veri üyeleriTupleözelliklerdir.
C# dili belirtimi
Daha fazla bilgi için aşağıdaki özellik teklifi notlarına bakın:
- Tanımlama grubu adlarını (yani, aka. Tuple projeksiyon başlatıcıları) çıkar
==!=Tanımlama grubu türleri için ve desteği