In the event that a Conditional method is compiled away, the arguments to each invocation are still type-checked at compile time. What is the motivation for this? Example:
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int x = 2;
string st = "";
// this invocation compiles fine
ConditionalMethod(x, st);
// this invocation won't compile
ConditionalMethod(st, x);
}
[Conditional("condition")]
public static void ConditionalMethod(int x, string st) { }
}
}
To be clear, the conditional symbol "condition" is not defined in this context, so the method invocations are omitted from the MSIL resulting from compilation. This is on par with the spec defined here, so no surprises there. Imagine a more complex scenario:
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ConditionalMethod(new Bar());
}
[Conditional("condition")]
public static void ConditionalMethod(Foo foo) { }
public class Foo { }
#if condition
public class Bar : Foo { }
#else
public class Bar { }
#endif
}
}
Invocations of 'ConditionalMethod' will only be included in the resulting compilation when the conditional symbol "condition" is defined. In that scenario, however, Bar CAN in fact be upcast to Foo. If the compiler knows that invocations to 'ConditionalMethod' will be compiled away, shouldn't it also be aware that in the event that we care about invocations of this method, this code will be legit? Yes, this is a contrived and hair-splitting example, but it helps illustrate my question. I'm asking out of benign curiosity, as this has irked me for quite some time now. Please help, Jon Skeet. :)
Imagine this code
A method's signature is a critical part of associating a call to the method that should be called. That association must be made before it is known whether the Conditional attribute applies. In the example above, the call does not match any of the methods. The compiler would have to make a leap of faith to guess that you meant the Blah(int,string). But it would be a guess, because the the signature doesn't match (the argument types are in the wrong order). Blah(string,int,int) is also pretty close - you just forgot an argument. And Blahh(string,int) is close too - you just made a typo in the name.
For a similar example, see this blog post by Eric Lippert (who knows this stuff).
and later