2010-01-14 11 views
5

पर सशर्त विशेषता मैं सोच रहा हूं कि जब आप एक सिस्टम को डालते हैं तो डायग्नोस्टिक्स। शर्त ("DEBUG") बेस क्लास में वर्चुअल विधि पर विशेषता है जिसे आपको व्युत्पन्न कक्षाओं पर कंपाइलर त्रुटियां नहीं मिलती हैं उस वर्चुअल विधि को ओवरराइड करें लेकिन स्थिति पूरी होने पर सशर्त विशेषता नहीं है। उदाहरण:वर्चुअल फ़ंक्शन

public class MyBaseClass 
{ 
    [System.Diagnostics.Conditional("DEBUG")] 
    public virtual void Test() 
    { 
     //Do something 
    } 
} 

public class MyDerivedClass : MyBaseClass 
{ 
    public override void Test() 
    { 
     //Do something different 
    } 
} 

ऐसा लगता है कि जब डीबग परिभाषित नहीं है, सशर्त अनिवार्य रूप से एक sitation जहां ओवरराइड विधि वास्तविक आईएल उत्पादन में कोई आभासी समारोह है क्योंकि वहाँ मौजूद नहीं कर सकते हो जाएगा। फिर भी मेरे परीक्षण में, संकलक कोड को जेनरेट करने के लिए ठीक लगता है। क्या सशर्त बस फंक्शन बॉडी के लिए आईएल फेंकता है लेकिन कक्षा हस्ताक्षर में कोई वास्तविक बदलाव नहीं करता है?

+0

मूर्तिकला: बेस क्लास के वर्चुअल से सशर्त विशेषता को व्युत्पन्न क्लास के ओवरराइड परिणामों में एक कंपाइलर त्रुटि में स्थानांतरित करना। यह जवाब में विस्तृत व्यवहार पर विचार कर समझ में आता है। – devgeezer

उत्तर

5

मुझे लगता है कि ऐसा इसलिए है क्योंकि विशेषता केवल उस पद्धति को कॉल को अनदेखा करके कॉल करने योग्य नहीं है, लेकिन विधि मौजूद है।

संपादित करें: मैं आगे बढ़ गया और इसके साथ थोड़ा सा प्रयोग किया और यदि आप प्रतिबिंबक में निम्न कोड का रिलीज निर्माण का निरीक्षण करते हैं, तो आप टेस्ट विधि को अनुपस्थित होने पर कॉल देखेंगे।

public class TestClass 
    { 
     [ConditionalAttribute("DEBUG")] 
     public static void Test() 
     { 
      Console.WriteLine("Blierpie"); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine("Starting test"); 
      TestClass.Test(); 
      Console.WriteLine("Finished test"); 
      Console.ReadKey(); 
     } 
    } 
+0

हां, यह सही है - एमएसडीएन का कहना है, "कंपाइलर्स को इंगित करता है कि एक विधि कॉल या विशेषता को अनदेखा किया जाना चाहिए जब तक एक निर्दिष्ट सशर्त संकलन प्रतीक परिभाषित नहीं किया जाता है।" – Matthias

1

Anton सही है। समारोह वहां है लेकिन इसे सीधे कॉल किया जाता है। लेकिन आप अभी भी प्रतिबिंब का उपयोग कर इसे कॉल कर सकते हैं।

 MyDerivedClass myDerivedClass = new MyDerivedClass(); 
     //Following will not work in Release configuration 
     myDerivedClass.Test(); 
     //But it exist and you can still call it using reflection 
     myDerivedClass.GetType().GetMethod("Test").Invoke(myDerivedClass, null); 
     //It name will still appear. 
     foreach (MethodInfo method in myDerivedClass.GetType().GetMethods()) 
      Console.WriteLine(method.Name); 
1

अधिक दिलचस्प मामला यह एक है:

class Program { 
    static void Main(string[] args) { 
     new Derived().Test(); 
    } 
} 
public class Base { 
    [System.Diagnostics.Conditional("DEBUG")] 
    public virtual void Test() { Console.WriteLine("base"); } 
} 

public class Derived : Base { 
    public override void Test() { 
     base.Test(); 
    } 
} 

}

आप इस पर Ildasm.exe चलाते हैं, तो आप देखेंगे कि यह वास्तव में Base.Test का उत्सर्जन करता है() विधि, लेकिन आधार को छोड़ देता है। टेस्ट() कॉल। दूसरे शब्दों में, [सशर्त] विधियों को छोड़ नहीं देता है, यह विधि कॉल को छोड़ देता है।

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