I\'m building a DLL class library - I want to make it usable by as many people as possible. Which version of the .NET Framework and which C# version should I use? Is it po
We target multiple runtime versions concurrently (.NET 1.1, .NET 2.0, and .NET 3.5) for some products.
We handle this in several ways:
eg:
\ProductFoo_1_1.sln (.NET 1.1 solution, VS 2003) \ProductFoo_2_0.sln (.NET 2.0 solution, VS 2008) \ProductFoo_3_5.sln (.NET 3.5 solution, VS 2008) \FooLibrary\FooLibrary_1_1.csproj (.NET 1.1 Project, VS 2003) \FooLibrary\FooLibrary_2_0.csproj (.NET 2.0 Project, VS 2008) \FooLibrary\FooLibrary_3_5.csproj (.NET 3.5 Project, VS 2008) \FooLibrary\FooClass.cs (shared amongst all Projects) \FooLibrary\FooHelpers_1_1.cs (only referenced by the .NET 1.1 project) \FooService\FooService_3.5.csproj (.NET 3.5 Project, VS 2008) \FooService\FooService.cs
Defining NET_X_X
symbols in each of the solutions
For .NET Framework specific code, we use preprocessor instructions such as this:
public void SomeMethod(int param) { #ifdef NET_1_1 // Need to use Helper to Get Foo under .NET 1.1 Foo foo = Helper.GetFooByParam(param); #elseif NET_2_0 || NET_3_5 // .NET 2.0 and above can use preferred method. var foo = new Foo { Prop = param }; foo.LoadByParam(); #endif foo.Bar(); } #ifdef NET_3_5 // A method that is only available under .NET 3.5 public int[] GetWithFilter(Func Filter) { // some code here } #endif
For clarification, the above lines starting with # are preprocessor commands. When you compile a solution, the C# Compiler (csc) pre-processes the source files.
If you have an #ifdef
statement, then csc will evaluate to determine if that symbol is defined - and if so, include the lines within that segment when compiling the project.
It's a way to mark up code to compile in certain conditions - we also use it to include more intensive debugging information in specific verbose debug builds, like so:
#if DEBUG_VERBOSE Logging.Log("Web service Called with parameters: param = " + param); Logging.Log("Web service Response: " + response); Logging.Log("Current Cache Size (bytes): " + cache.TotalBytes); // etc. #endif
It does make things more complicated, so we only tend to do it where we need to maintain a legacy .NET 1.1 or 2.0 instance (eg where a customer can't/won't upgrade).
I imagine that when .NET 4.0 rolls around, we'll do the same thing and just add a NET_4_0 symbol.