2013-03-12 7 views
5

मैंने ओवरलोडिंग विधियों के साथ एक समस्या को पार किया है जिसमें अलग-अलग बाधाएं हैं जो अनन्य लगती हैं। यह मेरा उदाहरण है:पहले से ही विभिन्न प्रकार की बाधाओं के साथ परिभाषित एक ही हस्ताक्षर वाले सदस्य

public class A 
{ 
    public void Do<T>() where T : class 
    { 

    } 

    public void Do<T>() where T : struct 
    { 

    } 
} 

और यह निम्न त्रुटि "पहले से परिभाषित उसी हस्ताक्षर वाले सदस्य" के साथ संकलित नहीं है। क्या दोनों स्थितियों को एक बार में संतुष्ट करना संभव है या यह सी # कंपाइलर की सीमा है?

उत्तर

8

यह संकलक की एक सीमा नहीं है - यह भाषा की एक सीमा है (और काफी CLR संभवतः के साथ-साथ, मुझे यकीन है कि नहीं कर रहा हूँ)।

मूल रूप से वे ओवरलोड को दबा रहे हैं - यह रिटर्न प्रकार से ओवरलोड करने की कोशिश की तरह है। यह समर्थित नहीं है।

यह ऐसी है कि इन कॉल सभी विभिन्न तरीकों में से आमंत्रण के लिए संकलन तरीकों घोषित करने के लिए संभव है:

a.Do<int>(); 
a.Do<string>(); 
a.Do<int?>(); 

... लेकिन यह हमेशा वैकल्पिक पैरामीटर और/या पैरामीटर सरणियों शामिल है, और यह horrible है।

यह भी ध्यान रखें कि यद्यपि आप सामान्य बाधाओं से ओवरलोड नहीं कर सकते, तो आप जेनेरिक "arity" (प्रकार पैरामीटर की संख्या) द्वारा अधिभार कर सकते हैं:

public void Foo() {} 
public void Foo<T>() {} 
public void Foo<T1, T2>() {} 
+0

कम से कम मुझे आशा है कि यह कहना है कि इन दो बाधाओं अनन्य हैं सही था और यह सिर्फ सीमा है , सही? :) –

+0

@IlyaChernomordik: यह एक सीमा है, लेकिन एक बहुत ही उचित एक आईएमओ है। –

+0

लेकिन यह अनुमति देने में क्या गलत है? मुझे बस एक वर्ग है (मैं जांच सकता हूं कि यह शून्य है या नहीं) के आधार पर अलग-अलग कार्रवाइयां करने की ज़रूरत है या जब यह बहुत लंबा हो (तब मुझे पता है कि मूल्य वहां है)। तो जिस तरीके से लगता है कि अलग-अलग तरीकों को अलग-अलग नाम देना चाहिए। मैं निश्चित रूप से भयानक तरीके से उपयोग नहीं करना चाहता :) :) –

2

आप varing द्वारा एक विधि को ओवरलोड नहीं कर सकते सामान्य पैरामीटर कंटेनर। वैध विधि अधिभार के लिए आपको विधि में अलग-अलग इनपुट पैरामीटर होना चाहिए।

1

दोनों तरीकों का पालन नाम जब संकलित होना चाहिए:

A.Do``1 

सामान्य मापदंडों की गिनती के रूप में विधि या वर्ग के नाम में चला जाता है।

सुनिश्चित नहीं हैं कि अपनी स्थिति है, लेकिन आप उन तरीकों कॉल करने के लिए प्रतिबिंब का उपयोग करने की आवश्यकता हो सकती:

public class A 
{ 
    public void Do<T>() 
    { 
     if(typeof(T).IsValueType){ 
      // nasty reflection to call DoValueType 
     } 
     else { 
      // nasty reflection to call DoReferenceType 
     } 
    } 
    private void DoReferenceType<T>() where T : class { 

    } 
    private void DoValueType<T>() where T : struct { 

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