Gördüğüm gibi, bir Tuple bir sonuç sınıfı yazmak için bir kısayoldur (başka kullanımlar da olduğundan eminim).
Gerçekten de başka değerli kullanımlar da vardırTuple<>
- bunların çoğu, benzer bir yapıyı paylaşan belirli bir grup grubun semantiğinin soyutlanmasını ve basitçe sıralı değerler kümesi olarak ele alınmasını içerir. Her durumda, tuples'ın bir avantajı, ad alanınızı, özellikleri göstermeyen ancak yöntemleri değil yalnızca veri sınıflarıyla karıştırmaktan kaçınmalarıdır.
Aşağıda makul bir kullanım örneği verilmiştir Tuple<>
:
var opponents = new Tuple<Player,Player>( playerBob, playerSam );
Yukarıdaki örnekte bir çift rakibi temsil etmek istiyoruz, bir grup yeni bir sınıf yaratmak zorunda kalmadan bu örnekleri eşleştirmenin uygun bir yoludur. İşte başka bir örnek:
var pokerHand = Tuple.Create( card1, card2, card3, card4, card5 );
Bir poker eli sadece bir kart seti olarak düşünülebilir ve bu kavramı ifade etmenin makul bir yolu olabilir.
Tuples'ın noktasını kaçırmama ihtimalini bir kenara bırakırsak, Tuple ile örnek kötü bir tasarım seçimi midir?
Tuple<>
Genel tür için genel bir API'nın parçası olarak güçlü yazılan örnekleri döndürmek nadiren iyi bir fikirdir. Kendinizi tanıdığınız gibi, tuples ilgili tarafların (kütüphane yazarı, kütüphane kullanıcısı) kullanılan tuple tiplerinin amacı ve yorumu konusunda önceden anlaşmasını gerektirir. Sezgisel ve açık API'lar oluşturmak için yeterince zorlayıcıdır, Tuple<>
yalnızca herkese açık olarak API'nın amacını ve davranışını gizler.
Anonim türler de bir tür gruptur - ancak, güçlü bir şekilde yazılırlar ve türe ait özellikler için açık, bilgilendirici adlar belirtmenize izin verir. Ancak anonim türlerin farklı yöntemlerde kullanılması zordur - öncelikle projeksiyonların normalde ad atamak istemeyeceğimiz türler üreteceği LINQ gibi teknolojileri desteklemek için eklenmiştir. (Evet, aynı tür ve adlandırılmış özelliklere sahip anonim türlerin derleyici tarafından birleştirildiğini biliyorum).
Temel kuralım: Genel arayüzünüzden döndürürseniz - adlandırılmış bir tür yapın .
Tuples'ı kullanmanın diğer temel kuralı şudur: name yöntemi argümanları ve türün localc değişkenleri Tuple<>
olabildiğince açık bir şekilde - adı, grubun öğeleri arasındaki ilişkilerin anlamını temsil ettirin . var opponents = ...
Örneğimi düşün .
Aşağıda, yalnızca kendi derlememde kullanmak üzere yalnızcaTuple<>
veri türü bildirmekten kaçındığım gerçek dünya örneği örneği . Durum, anonim türler içeren genel sözlükler kullanırken, yöntem adında bulunamayan bir parametre gerektirdiğinden, sözlükteki öğeleri bulmak için yöntemi kullanmak zorlaşır :TryGetValue()
out
public static class DictionaryExt
{
// helper method that allows compiler to provide type inference
// when attempting to locate optionally existent items in a dictionary
public static Tuple<TValue,bool> Find<TKey,TValue>(
this IDictionary<TKey,TValue> dict, TKey keyToFind )
{
TValue foundValue = default(TValue);
bool wasFound = dict.TryGetValue( keyToFind, out foundValue );
return Tuple.Create( foundValue, wasFound );
}
}
public class Program
{
public static void Main()
{
var people = new[] { new { LastName = "Smith", FirstName = "Joe" },
new { LastName = "Sanders", FirstName = "Bob" } };
var peopleDict = people.ToDictionary( d => d.LastName );
// ??? foundItem <= what type would you put here?
// peopleDict.TryGetValue( "Smith", out ??? );
// so instead, we use our Find() extension:
var result = peopleDict.Find( "Smith" );
if( result.First )
{
Console.WriteLine( result.Second );
}
}
}
PS Sözlüklerde anonim türlerden kaynaklanan sorunların üstesinden gelmenin başka bir (daha basit) yolu var ve bu, var
derleyicinin sizin için türü 'çıkarmasına' izin vermek için anahtar kelimeyi kullanmaktır . İşte bu sürüm:
var foundItem = peopleDict.FirstOrDefault().Value;
if( peopleDict.TryGetValue( "Smith", out foundItem ) )
{
// use foundItem...
}