虚函数的条件属性

时间:2010-01-14 19:06:38

标签: c#

我想知道为什么当您在基类中的虚方法上放置System.Diagnostics.Conditional(“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
    }
}

似乎在没有定义DEBUG时,条件基本上会在不存在覆盖方法的情况下引用,因为实际的IL输出中没有虚函数。然而在我的测试中,编译器似乎生成代码就好了。条件是否只是为函数体抛出IL而不是对类签名进行任何实际更改?

3 个答案:

答案 0 :(得分:5)

我认为这是因为该属性仅通过忽略对该方法的调用来指示该方法不可调用,但该方法确实存在。

编辑: 我继续尝试了一下这个,如果你在Reflector中检查下面代码的发布版本,你会注意到没有对Test方法的调用。

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

答案 1 :(得分: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);

答案 2 :(得分: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()方法,但省略了base.Test()调用。换句话说,[Conditional]不会省略方法,它会省略方法调用。