views:

248

answers:

3

I've recently found the need to check at compile-time whether either: a) a certain assembly reference exists and can be successfully resolved, or b) a certain class (whose fully qualified name is known) is defined. These two situations are equivalent for my purposes, so being able to check for one of them would be good enough. Is there any way to do this in .NET/C#? Preprocessor directives initially struck me as something that might help, but it seems it doesn't have the necessary capability.

Of course, checking for the existence of a type at runtime can be done easily enough, but unfortunately that won't resolve my particular problem in this situation. (I need to be able to ignore the fact that a certain reference is missing and thus fall-back to another approach in code.)

+1  A: 

Is there a reason you can't add a reference and then use a typeof expression on a type from the assembly to verify it's available?

var x = typeof(SomeTypeInSomeAssembly);

If the assembly containing SomeTypeInSomeAssembly is not referenced and available this will not compile.

JaredPar
Yeah. Unfortunately it has to be at compile-time, else the compiler will attempt to compile that time and see that it's missing. Of course, I could just define my own type with the same structure/signature, but that seems very hack to me.
Noldorin
+1  A: 

It sounds like you want the compiler to ignore one branch of code, which is really only doable by hiding it behind an #if block. Would defining a compiler constant and using #if work for your purposes?

#if MyConstant
.... code here that uses the type ....
#else
.... workaround code ....
#endif

Another option would be to not depend on the other class at compile-time at all, and use reflection or the .NET 4.0 dynamic keyword to use it. If it'll be called repeatedly in a perf-critical scenario in .NET 3.5 or earlier, you could use DynamicMethod to build your code on first use instead of using reflection every time.

Jonathan
This is probably closer to what I need. I was myself considering using an #if directive along with a pre-build script that defines a constant if and only if a certain reference can be resolved.
Noldorin
A: 

I seem to have found a solution here, albeit not precisely for what I was initially hoping.

My Solution:

What I ended up doing is creating a new build configuration and then defining a precompiler constant, which I used in code to determine whether to use the reference, or to fall back to the alternative (guaranteed to work) approach. It's not fully automatic, but it's relatively simple and seems quite elegant - good enough for my purposes.

Alternative:

If you wanted to fully automate this, it could be done using a pre-build command that runs a Batch script/small program to check the availabilty of a given reference on the machine and then updates a file containing precompiler constants. This however I considered more effort than it was worth, though it may have been more useful if I had multiple independent references that I need to resolve (check availability).

Noldorin