जिस तरह से मैं इसे देखता हूं, एक ट्यूपल एक परिणाम वर्ग लिखने का एक शॉर्टकट है (मुझे यकीन है कि अन्य उपयोग भी हैं)।
वास्तव में अन्य मूल्यवान उपयोग हैं Tuple<>
- उनमें से अधिकांश में एक विशेष प्रकार के समूह के शब्दार्थ को अलग करना शामिल है जो एक समान संरचना साझा करते हैं, और उन्हें केवल मानों के सेट के रूप में व्यवहार करते हैं। सभी मामलों में, टुपल्स का एक लाभ यह है कि वे आपके नाम स्थान को केवल डेटा वर्ग के साथ अव्यवस्थित करने से बचते हैं जो गुणों को उजागर करते हैं, लेकिन विधियां हैं।
यहाँ के लिए एक उचित उपयोग का एक उदाहरण है Tuple<>
:
var opponents = new Tuple<Player,Player>( playerBob, playerSam );
उपरोक्त उदाहरण में हम विरोधियों की एक जोड़ी का प्रतिनिधित्व करना चाहते हैं, एक टपल एक नया वर्ग बनाने के बिना इन उदाहरणों को बाँधने का एक सुविधाजनक तरीका है। यहाँ एक और उदाहरण है:
var pokerHand = Tuple.Create( card1, card2, card3, card4, card5 );
एक पोकर हाथ को कार्ड के एक सेट के रूप में माना जा सकता है - और टपल (हो सकता है) उस अवधारणा को व्यक्त करने का एक उचित तरीका है।
इस संभावना को दरकिनार करते हुए कि मैं टुपल्स की बात को याद कर रहा हूं, क्या टुपल के साथ एक खराब डिजाइन का उदाहरण है?
Tuple<>
एक सार्वजनिक प्रकार के लिए एक सार्वजनिक एपीआई के हिस्से के रूप में दृढ़ता से टाइप किए गए उदाहरणों को वापस करना शायद ही कभी एक अच्छा विचार है। जैसा कि आप स्वयं को पहचानते हैं, ट्यूपल्स में शामिल दलों की आवश्यकता होती है (पुस्तकालय लेखक, पुस्तकालय उपयोगकर्ता), समय-समय पर उपयोग किए जाने वाले ट्यूपल प्रकारों के उद्देश्य और व्याख्या पर सहमत होते हैं। यह एपीआई बनाने के लिए पर्याप्त चुनौतीपूर्ण है जो सहज और स्पष्ट है, Tuple<>
सार्वजनिक रूप से केवल एपीआई के इरादे और व्यवहार को अस्पष्ट करता है।
बेनामी प्रकार भी एक प्रकार का टपल है - हालांकि, वे दृढ़ता से टाइप किए जाते हैं और आपको प्रकार से संबंधित गुणों के लिए स्पष्ट, सूचनात्मक नाम निर्दिष्ट करने की अनुमति देते हैं। लेकिन अनाम प्रकारों को विभिन्न तरीकों से उपयोग करना मुश्किल है - उन्हें मुख्य रूप से LINQ जैसी तकनीकों का समर्थन करने के लिए जोड़ा गया था जहां अनुमान ऐसे प्रकारों का उत्पादन करेंगे जिनसे हम सामान्य रूप से नाम निर्दिष्ट नहीं करना चाहेंगे। (हां, मुझे पता है कि समान प्रकार और नामित गुणों के साथ अनाम प्रकार संकलक द्वारा समेकित होते हैं)।
अंगूठे का मेरा नियम है: यदि आप इसे अपने सार्वजनिक इंटरफ़ेस से वापस कर देंगे - इसे एक नामांकित प्रकार बनाएं ।
Tuples का उपयोग करने के लिए अंगूठे का मेरा अन्य नियम है: नाम विधि तर्क और प्रकार के स्थानीय चर Tuple<>
स्पष्ट रूप से संभव के रूप में - नाम को tuple के तत्वों के बीच संबंधों के अर्थ का प्रतिनिधित्व करते हैं। मेरे var opponents = ...
उदाहरण के बारे में सोचो ।
यहां एक वास्तविक दुनिया का एक उदाहरण है जहां मैंने केवल अपनी विधानसभा के भीतर उपयोग के लिएTuple<>
डेटा-केवल प्रकार घोषित करने से बचने के लिए उपयोग किया है । स्थिति में यह तथ्य शामिल है कि जब सामान्य प्रकारों वाले अनाम शब्दकोशों का उपयोग किया जाता है 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 वहाँ शब्दकोशों में गुमनाम प्रकार से उत्पन्न होने वाले मुद्दों के आसपास का एक और (सरल) तरीका है, और यह है कि var
कंपाइलर का उपयोग करके 'कंपाइलर' को आपके लिए टाइप करें। यहाँ वह संस्करण है:
var foundItem = peopleDict.FirstOrDefault().Value;
if( peopleDict.TryGetValue( "Smith", out foundItem ) )
{
// use foundItem...
}