How to inject C# Preprocessor Directives to an interface by Reflection ?
Example :
I want to inject #if SILVERLIGHT to any WCF service contract interface.
Short answer: you can't.
Slightly longer answer: you question doesn't even make sense in the first place.
Preprocessor directives are processed before compilation. The result of that processing is the new, modified, source code. That source code then gets compiled.
For example, if the SILVERLIGHT symbol is not defined at the time of compilation, then the whole code between #if SiLVERLIGHT and #endif will be completely ignored by the compiler as if it wasn't even there.
That's not possible. As per the name, preprocessor directives exist only just before compile time. Nowhere else.
Related
I have a C# program where some parts of code are generated using D-style mixins (i.e., the body of the method is compiled, executed, and results inserted into a class). The method is marked with [MixinAttribute] and, naturally, I don't want it to be compiled into the program. Is there some cheap way of preventing the method decorated with this attribute from being included in a build?
The only way is with compiler conditionals:
#if DEBUG
[MixinAttribute]
// method you don't want included
#endif
The problem with this approach is that you then create a member which will be unavailable in builds where DEBUG is not defined. You then have to mark all usages with the conditional, and I don't think this is what you want. It's not quite clear but I think what you are really asking is how you create dynamic call sites at build time, or, rather, at JIT time (which is what the ConditionalAttribute controls). If this is the case, you can't really do this easily in C# without using some kind of dynamic dispatch overriding (using some proxying library) or by using some post-processing tool like PostSharp to manipulate the compiler output.
In .Net, is the attribute feature used at compile-time or run-time or both? Can you give me some examples?
Most are used at runtime only. A very limited number are used by the compiler, including:
[Conditional(...)] - omit method calls per build symbols
[Obsolete(...)] - emit a warning/error as build output
[Serializable] - gets written as a CLI flag
[Extension] - used for extension methods
[AttributeUsage] - affects how attributes are applied
-
There are a range of things like [AssemblyVersion], [AssemblyFileVersion] etc that are used by the compiler when creating the assembly file, and things like [InternalsVisibleTo] which affect accessibility.
Additionally, tools like PostSharp do extra post-compile steps based on attributes.
There are some other attributes that the compiler may add to generated types/methods (for anon-methods / types, iterator blocks, etc).
Attributes are output as metadata to the assembly at compile time. This meta data is then used at runtime via reflection - for example using GetCustomAttributes().
Some attributes are used by the compiler at compile time, too. For example the compiler looks at the AttributeUsageAttribute to determine if an attribute can be used for a specific object.
Attributes are compiled into the code at compile time, but they are often used at runtime as triggers to do things differently.
The compiler adds what is called metadata to the object that is decorated with an attribute. This metadata, whether created via attributes or otherwise, is all accessible at run-time thru Reflection. Thus, you can decorate with attributes and then read the details when the program is running. However, to say that the metadata is "used" at compile time isn't quite correct, as the compiler doesn't care what metadata there is.
Having recently learned of the DebuggerDisplay attribute, I've found it quite useful. However, one thing that surprises me is that it doesn't have a [ConditionalAttribute("DEBUG")] attribute attached to it. Is there some way to force this or is it a bad idea to try? Or does it not matter for some other reason?
The [ConditionalAttribute("DEBUG")] is only used for optimising out method calls.
If you really want to remove these from your builds you can use #ifdef so that the code is only compiled in release mode.
One thing to bear in mind is that you can still debug binaries in release mode, as long as you have the pdb files it shouldn't matter. Release mode just clears up variables sooner and applies some compiler optimisations
As I often have to debug things in Release configuration builds that don't have the DEBUG directive, I would not want these hints to the debugger to be removed.
However, if you have some proprietary or confidential information in the way you display things when debugging that you don't want to make it into your release build, you may want to consider using the ConditionalAttribute or #if/#elif/#endif preprocessor directives to control what is emitted into your release builds.
For example, you could do:
#if DEBUG
[DebuggerDisplay...]
#endif
public class MyAwesomeClass
{
}
This would ensure the attribute is only emitted when the DEBUG directive is given.
I'll share a pattern that I've come to appreciate using partial.
public partial class MyClass{
//class details here
}
And then elsewhere:
#if DEBUG
[DebuggerDisplay("DebuggerValue")]
public partial class MyClass{
//anything needed for debugging purporses
}
#endif
This gives the ability to use DebuggerDisplay or other attributes without cluttering-up the base class.
I've been using a handful of files, all wrapped in #if DEBUG to hold these Debug-Partials. It helps keep the core classes cleaner and I don't have to remember to start/end compiler directives for each attribute.
I would think it would be a bad idea, because a lot of times the thing you're attaching the attribute to has some other use besides just showing it in the debugger, IMO.
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.)
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.
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.
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).
The aim is to be able to switch debugging calls on at run-time from database on a production build ...
No; the point of conditional methods and preprocessor directives is that they cause the compiler to omit code from the final executable. The runtime equivalent of these is an if statement.
However, aspect-orientated programming is roughly equivalent to what you're asking, in that it allows you to inject code into a running program that wouldn't otherwise be there.
Edit: as Joe mentioned, the way to do this is to program against a logging framework like log4net that allows fine-grained control over what gets logged.
Not at the pre-processor level. After all, you're running the result of that process. Of course, you could change your pre-processor checks to be normal code checks, which can obviously be switched as required.
No, but most logging subsystems provide this ability. E.g. with log4net you can change the logging level dynamically, or if using System.Diagnostics.Trace you can change the TraceSwitch level dynamically.
You obviously can't affect the binary code as such (as with the #if statement).
What I usually do is to make sure that my code contains a lot of logging, that is activated by trace switches. That way you can have a system run in production with little or no logging, and when you want to research some problem you can switch logging on by altering the config file.