开发者

Conditional attribute on a virtual function

I'm wondering why when you put a System.Diagnostics.Conditional("DEBUG") attribute on the a virtual method in a base class that you don't get compiler errors on derived classes that override that same virtual method but don't have the conditional attribute when the condition isn't met. Example:

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

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

It seems that when DEBUG is not defined, the conditional would essentially make a sit开发者_StackOverflow中文版ation where the override method can't exist because there is no virtual function in the actual IL output. Yet in my testing, the compiler seems to generate the code just fine either way. Does the conditional just throw out the IL for the function body but not make any real changes to the class signature?


I think this is because the attribute only indicates the method as not being callable by ignoring calls to that method, but the method does exist.

Edit: I went ahead and experimented a bit with this and if you inspect a release build of the following code in Reflector, you'd notice the call to the Test method being absent.

 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();
        }
    }


The more interesting case is this one:

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();
    }
}

}

If you run Ildasm.exe on this, you'll see that it actually emits the Base.Test() method, but omits the base.Test() call. In other words, [Conditional] doesn't omit methods, it omits method calls.


Anton is right. The function is there but a direct call to it is ignored. But you can still call it using reflection.

        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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜