2010-07-12 10 views
6

इसलिए मुझे एक कक्षा तैयार करना है जो युग्मित वस्तुओं के संग्रह पर काम करता है। वस्तुओं के बीच एक-से-एक मैपिंग है। मैं उम्मीद करता हूं कि कक्षा के ग्राहक ने मेरी कक्षा का उपयोग करने से पहले इस मैपिंग की स्थापना की है।जोड़े में वस्तुओं के लिए पूछने का सबसे सहज तरीका क्या है?

मेरा प्रश्न क्या मेरी कक्षा के उपयोगकर्ता मुझे उस जानकारी देने के लिए अनुमति देने के लिए सबसे अच्छा तरीका क्या है?

क्या यह इस तरह के जोड़े के संग्रह के लिए पूछना है?

MyClass(IEnumerable<KeyValuePair<Object, Object>> objects) 

या इस तरह के अलग संग्रह?

MyClass(IEnumberable<Object> x, IEnumerable<Object> y) 

या वहां एक और विकल्प है?

मैं पहली बार क्योंकि संबंध स्पष्ट है, मैं इसे अतिरिक्त काम यह ग्राहक पर डालता है की वजह से पसंद नहीं है पसंद है।

मैं दूसरी तरह क्योंकि प्रकार अधिक आदिम कर रहे हैं और कम काम की आवश्यकता होती है, मैं इसे पसंद नहीं है क्योंकि मानचित्रण स्पष्ट नहीं है। मुझे लगता है कि आदेश सही है।

राय कृपया?

+0

मैं एक ही कारण के लिए पहली पसंद है, संबंध स्पष्ट है। चूंकि KeyValuePair फ्रेमवर्क में आम है, मुझे कोई "अतिरिक्त काम" नहीं दिख रहा है यह एक दोष है कि KeyValuePair यह अनुमान लगाता है कि टी 2 किसी भी तरह टी 1 द्वारा कुंजी है, यदि उनके बीच का रिश्ता अधिक सेमिटिक है, आप अपना खुद का प्रकार रोल कर सकते हैं (यानी जोड़ी )। – Tergiver

उत्तर

10

.NET 4 में आप Tuple<T1,T2> का उपयोग करना चाहिए। एमएसडीएन में Tuple कक्षा पर अधिक जानकारी।

+6

केवल .NET 4: http://msdn.microsoft.com/en-us/library/dd268536.aspx#versionsTitleToggle – Hound

+1

तर्क के लिए। अपनी खुद की जोड़ी कक्षा के बजाय ट्यूपल का उपयोग क्यों करें? –

+0

@ कोर्बिनियन - मैंने यही सोचा, लेकिन एमएसडीएन ने मुझे "पिछले संस्करणों" के लिंक को शामिल करके फेंक दिया जिसमें .NET 3.5 शामिल है। दुर्भाग्यवश, वहां टिप्पणियां (जो मैंने नहीं देखी) सचमुच वास्तविकता को इंगित करती है कि यह केवल .NET 4. – tvanfosson

1

पहले, मेरे पसंदीदा तरीका है के रूप में एक अनुक्रम दूसरे के साथ अन्य की तुलना में लंबे समय तक हो सकता है - यह आवश्यक 1 प्रबंधित नहीं करता है: 1 मानचित्रण।

1

मेरी राय में, दूसरा विकल्प दोनों आप और ग्राहक करने के लिए अधिक काम देता है। पहला विकल्प गलत पाने के लिए सुरक्षित और कठिन है। मैं हर बार ऐसा पहला विकल्प या कुछ पसंद करूंगा।

+0

हां, मैंने यही कहा। –

0

मुझे लगता है कि आपको विकल्प 1 के साथ जाना है। इसमें स्पष्ट संबंध शामिल होना चाहिए या आप केवल परेशानी के लिए पूछ रहे हैं।

5

आप इसे करने के लिए उपयोग किया है, Tuple<T, R> का उपयोग करें। यदि आप नहीं करते हैं, तो बस एक सामान्य Tuple या Pair अपनी खुद की कक्षा लिखें। मैं KeyValuePair का उपयोग करने से बचूंगा, सिर्फ इसलिए कि यह वर्बोज़ है और Dictionary के साथ एक सहयोग है।

+0

इसके अलावा, मैंने पिछली बार जांच की है, KeyValuePair एक्सएमएल को क्रमबद्ध नहीं करता है, इसलिए यह आपके लिए महत्वपूर्ण है अगर इसका उपयोग न करने का एक और अच्छा कारण है। – AaronLS

5

मैं उन दोनों के KeyValuePair को पसंद करूंगा जो आप उल्लेख करते हैं क्योंकि यह अधिक अभिव्यक्तिपूर्ण है और वस्तुओं के बीच संबंध रखता है।

लेकिन मैं एक ऐसी कक्षा तैयार करूंगा जो आपकी जोड़ी का संदर्भ रखे। यह मेरी राय में अधिक पठनीय है, और यह आपके वास्तविक कार्यों को व्यक्त करने के लिए अतिरिक्त कक्षा या संरचना बनाने के लिए कभी दर्द नहीं करता है।

(छद्म कोड)

class MyPair 
{ 
    public TypeA One; 
    public TypeB Two; 
} 

MyClass(IEnumerable<MyPair> objects) 

कुछ जवाब है, जो KeyValuePair के रूप में के रूप में पठनीय है में Tuple<,> का जिक्र नहीं है, लेकिन और अधिक लचीला के रूप में यह दो से अधिक मापदंडों हो सकते हैं।

[संपादित करें - एक अच्छा रातों के बाद tuples/वर्गों के बारे में अधिक गहराई से सो]

To Tuple or Not To Tuple

+0

MyPair को IENumerable क्यों लागू करना चाहिए? –

+0

@ एलेक्स, क्योंकि यह नहीं होना चाहिए :) आप सही हैं, और मुझे स्पष्ट रूप से सोने की जरूरत है। –

+0

इसके बारे में चिंता न करें - मैं नींद की बात से संबंधित हो सकता हूं :) –

0

मैं दूसरे संस्करण का उपयोग करूंगा (क्योंकि यह आसान है) + टिप्पणियां + स्थिर/गतिशील जांच। यदि आप कोड अनुबंध का उपयोग कर सकते हैं, तो यह सुनिश्चित करने का प्रयास करें कि संग्रह समान लंबाई के हैं, न कि शून्य। यदि नहीं, तो Debug.Assert के साथ-साथ if ... throw ArgumentException साथ भी ऐसा ही। वैकल्पिक रूप से, आप जोड़ी युक्त अपनी वस्तु बना सकते हैं, लेकिन फिर यदि आप जोड़ी के सदस्यों के लिए जेनेरिक का उपयोग करना चाहते हैं तो यह कठिन हो जाता है। इसके अलावा, जब आप एक वस्तु है कि एक कंटेनर में संग्रहित किया जा करने के लिए है बनाने के लिए, आप ठीक ढंग से लागू करने के लिए GetHashCode, Equals, आदि पहले "प्रभावी सी #" पुस्तक इस पर एक आइटम है की है।

एक सामान्य नियम के रूप में, मैं ओवर-इंजीनियर विधि हस्ताक्षर नहीं करना पसंद करता हूं।

0

मैं आम तौर पर 2-Arg कन्स्ट्रक्टर में प्रस्तुत करने वाले KeyValuePair निर्माता के साथ दोनों प्रदान करता हूं। दोनों ओर से लाभदायक।

+0

बस उत्सुक - मैं समझता हूं कि आप दो तर्क विधि से एक तर्क के साथ एक तर्क के लिए कैसे जा सकते हैं - आप इसे दूसरी तरफ कैसे करते हैं? –

+0

सार्वजनिक MyClass (KeyValuePair जोड़ी): यह (pair.Key, pair.Value) {} – benjismith

1

मैं निश्चित रूप से पहले पसंद करेंगे। आप कहते हैं कि स्पष्ट है, सह-संबंध के रूप में, और यह त्रुटि-रहित होता सेकंड से भी है जहाँ आप परीक्षण करने के लिए है कि दोनों एक ही संग्रह लंबाई के होते हैं की जरूरत है। बेशक, यह वास्तव में आपके द्वारा बनाई जा रही वास्तविक कक्षा के आधार पर, दोनों/तरीकों/प्रस्तावों के लिए उपयुक्त हो सकता है।

एक बात, यदि आप .NET 4.0 का उपयोग करते हैं, तो मैं KeyValuePair के बजाय Tuple<T1, T2> का उपयोग करने की अनुशंसा करता हूं।

0

मैं दो कारणों के लिए पहली विधि की तरह।

  1. वे> एक शब्दकोश < में उनके रिश्तों भंडारण कर रहे हैं वस्तु पहले से ही, वे तो बस बंद शब्दकोश हाथ कर सकते हैं के रूप में - कोई अतिरिक्त कोड की आवश्यकता है।

    IEnumerable<KeyValuePair<Object,Object>> GetMappedPairs() 
    { 
        foreach(var pair in _myCustomData) 
        { 
         yield return new KeyValuePair{Key = pair.ID, Value = pair.Data}; 
        } 
    } 
    

    विकल्प नंबर 2 नहीं है:

  2. वे तो एक IEnumerable में आप KeyValuePairs दे रही है अपने स्वयं के कस्टम संग्रहण का उपयोग कर रहे हैं, तो उपज बयान इस तरह

कुछ के साथ वास्तव में आसान है आपकी विधि का उपयोग कर डेवलपर्स द्वारा आसानी से समझ लिया जाता है, इसलिए इसका उपयोग करने के तरीके को समझाने के लिए दस्तावेज़ीकरण और टिप्पणियों की आवश्यकता होगी।

संयोग से, आप शायद एक सामान्य के बजाय कोडिंग KeyValuePair

MyClass<TKey,TValue>(IEnumerable<KeyValuePair<TKey,TValue>> pairs); 
0

मुश्किल यह कारण है कि आप सब पर एक गणनीय बेनकाब पर विचार लायक हो सकता है के रूप में अपने विधि की घोषणा के द्वारा सबसे अच्छा दिखाए जाएँगे। आप एक ऐड (ऑब्जेक्ट ए, ऑब्जेक्ट बी) विधि का उपयोग कर सकते हैं जो जोड़ों से निपटने के आपके आंतरिक तरीके को पूरी तरह से छुपाता है। ग्राहक तब सेट या अकेले के रूप में संबंध जोड़ने के अपने साधन स्थापित कर सकता था।

बेशक यदि आपको अभी भी एक गणना करने की विधि की आवश्यकता है, तो पहला विकल्प शायद सबसे अच्छा है: एक स्पष्ट संबंध। लेकिन आप का उपयोग कर या बनाने एक टपल या जोड़ी प्रकार KeyValuePair के बजाय का उपयोग करने, उन दोनों के बीच संबंध संभालने पर विचार मूल्य प्रकृति की कुंजी में से एक नहीं है।

0

अब क्या हुआ अगर आपने जैसे कुछ किया है?

// The client can choose to put together an IEnumerable<...> by hand...  
public MyClass(IEnumerable<KeyValuePair<object, object>> pairs) 
{ 
    // actual code that does something with the data pairs 
} 

// OR the client can pass whatever the heck he/she wants, as long as 
// some method for selecting the Xs and Ys from the enumerable data is provided. 
// (Sorry about the code mangling, by the way -- just avoiding overflow.) 
public static MyClass Create<T> 
(IEnumerable<T> source, Func<T, object> xSelector, Func<T, object> ySelector) 
{ 
    var pairs = source 
     .Select(
      val => new KeyValuePair<object, object>(
       xSelector(val), 
       ySelector(val) 
      ) 
     ); 

    return new MyClass(pairs); 
} 

यह ग्राहकों को इस तरह कोड लिखने की अनुमति होगी:

// totally hypothetical example 
var stockReturns = StockReturns.Create(prices, p => p.Close, p => p.PrevClose); 
संबंधित मुद्दे

 संबंधित मुद्दे