2014-11-17 8 views
6

अगर वहाँ इन दोनों तरीकों के बीच कोई अंतर है मैं सोच रहा हूँ के रूप में संग्रह के लिए मजबूर करने। दूसरा एक और प्राकृतिक दिखता है, लेकिन इसका उपयोग करने का एकमात्र कारण नहीं होना चाहिए। हो सकता है कि उनमें से कुछ से संबंधित कुछ प्रदर्शन मुद्दे या कुछ डायबॉलिक मैम्बोम्बो हैं?बाधा बनाम पैरामीटर - जिस तरह से पैरामीटर

void FirstMethod<T>(T a) where T : IEnumerable<Animal> 
{ 
    ... 
} 

void SecondMethod<T>(IEnumerable<T> a) where T : Animal 
{ 
    ... 
} 
+2

यह पैरामीटर के साथ आप जो करते हैं उस पर निर्भर करता है। दोनों समान नहीं हैं, लेकिन मतभेद किसी विशेष कार्यान्वयन के लिए जर्मन हो सकते हैं या नहीं भी हो सकते हैं। दोनों कार्यात्मक रूप से अलग हैं, इसलिए प्रदर्शन प्राथमिक चिंता नहीं होगी, यह वही है जो वे वास्तव में करेंगे। – Servy

उत्तर

6

अंतर यह है कि आप आसानी से दूसरी विधि, को IEnumerable<Dog> पारित कर सकते हैं, लेकिन जब आप इसे पहली विधि के पास यह सिर्फ परोक्ष एक IEnumerable<Animal>

करने के लिए परिवर्तित हो जाएगा पर एक नजर डालें है fiddle

संपादित टिप्पणी के लिए धन्यवाद @ सर्वी।

+3

आप यह सिर्फ परोक्ष एक 'IEnumerable करने के लिए परिवर्तित किया जाएगा भी पहले के लिए एक' IEnumerable 'पारित कर सकते हैं,'। – Servy

+1

'IENumerable ' को 'आउट' (कॉन्वेंट) के रूप में घोषित किया गया है। यह 'IENumerable ' ले सकता है। –

+0

इसे 'IENumerable ' के रूप में परिभाषित किया गया है, जिसका अर्थ यह है कि यह कॉन्वर्सेंट है। आप 'IEnumerable ' पर कास्ट कर सकते 'IEnumerable ' –

0

मैं LINQPad में इस नमूने की कोशिश की:

void Main() 
{ 
    var cats = new [] { new Cat() }; 
    FirstMethod(cats); 
    SecondMethod(cats); 
} 
interface Animal 
{ 
} 
class Cat : Animal 
{ 
} 
void FirstMethod<T>(T a) where T : IEnumerable<Animal> 
{ 
    var b = a.FirstOrDefault(); 
} 
void SecondMethod<T>(IEnumerable<T> a) where T : Animal 
{ 
    var b = a.FirstOrDefault(); 
} 

उत्पन्न आईएल कोड को देख कर, वहाँ तरीकों को 2 कॉल के बीच कोई अंतर नहीं है और वे दोनों cats पैरामीटर के रूप में स्वीकार करते हैं।

संपादित करें: मतभेदों के तरीकों में होते हैं, जैसा कि नीचे देखा। (आप @servy धन्यवाद टिप्पणी के लिए)

IL_001D: ldarg.0  
IL_001E: ldloc.0  // cats 
IL_001F: call  UserQuery.FirstMethod 
IL_0024: nop   
IL_0025: ldarg.0  
IL_0026: ldloc.0  // cats 
IL_0027: call  UserQuery.SecondMethod 

FirstMethod: 
IL_0000: nop   
IL_0001: ldarg.1  
IL_0002: box   02 00 00 1B 
IL_0007: call  System.Linq.Enumerable.FirstOrDefault 
IL_000C: stloc.0  // b 
IL_000D: ret   

SecondMethod: 
IL_0000: nop   
IL_0001: ldarg.1  
IL_0002: call  05 00 00 2B 
IL_0007: stloc.0  // b 
IL_0008: ret   

इस आईएल कोड पर एक decompiler का उपयोग करना दिखाता है, जहां मुक्केबाजी प्रकार सुरक्षा सुनिश्चित करने से होता है।

private void Main() 
{ 
    Cat[] a = new Cat[1] 
    { 
     new Cat() 
    }; 
    this.FirstMethod<Cat[]>(a); 
    this.SecondMethod<Cat>((IEnumerable<Cat>) a); 
} 

private void FirstMethod<T>(T a) where T : IEnumerable<Animal> 
{ 
    Enumerable.FirstOrDefault<Animal>((IEnumerable<Animal>) a); 
} 

private void SecondMethod<T>(IEnumerable<T> a) where T : Animal 
{ 
    Enumerable.FirstOrDefault<T>(a); 
} 
+0

दोनों संकलित करें। समान नहीं हैं (इसके अलावा दोनों विधियां कुछ भी नहीं करती हैं)। – Servy

+0

@ सर्वी मुझे समझ में नहीं आ रहा है कि आप क्यों कहते हैं कि वे समान नहीं हैं। मैंने चित्रण करने के लिए आईएल कोड जोड़ा है। दोनों ही तरीकों से दोनों बुला और क्रियान्वित –

+0

वे विभिन्न प्रकार स्वीकार करते हैं, अलग-अलग व्यवहार है, पैरामीटर है कि वे स्वीकार करते हैं, आदि के साथ अलग अलग बातें कर सकते हैं (एक एक IEnumerable है) वे दोनों संकलन यही कारण है कि इसका मतलब यह नहीं है कि वे कर रहे हैं में समान हैं समान। आपके उदाहरण में वे एकमात्र कारण हैं कि न तो कोई कार्यान्वयन है। अगर उनके पास कार्यान्वयन होते हैं तो वे सभी तरह के तरीके हैं जो वे अलग-अलग हो सकते हैं। – Servy

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