4

I'm writing a library, and I want a class to implement and make use of IReadOnlyList<T> if possible. However, that interface is only available starting at framework version 4.5, and I don't want to be tied to that version just because of this one interface.

Is there a way I can automatically compile two versions of the library, one for 4.5 (that will implement the interface, and possibly have some other features as well), and another for 3.5?

As an example, I'm looking for something like an MSBuild configuration that says "compile this library in two [or more] versions" and then specify different options for each one, like defined symbols, framework, references, etc.

If this is possible, it could actually solve a number of other similar problems I've been having.

GregRos
  • 8,667
  • 3
  • 37
  • 63
  • 1
    I liked the question better, when it said `and I was a class` :D – Nolonar Apr 15 '13 at 09:38
  • 1
    possible duplicate of [Conditional compilation depending on the framework version in C#](http://stackoverflow.com/questions/408908/conditional-compilation-depending-on-the-framework-version-in-c-sharp) – George Duckett Apr 15 '13 at 09:45
  • I'm sorry, I didn't realize a preprocessor directive would work for type definitions. However, the questions are not exactly the same. I'm specifically asking for a way to automatically compile two different versions of the library. – GregRos Apr 15 '13 at 09:48

2 Answers2

6

You could use a compiler directive, e.g.

#if NET45
//specific code for .NET 4.5
#endif

Then create two projects, one for each version, using the Project Linker to maintain a single codebase. In the .NET 4.5 project you can specify the NET45 variable on build. This way the code in the #if block will only be used in one of the versions.

Bas
  • 26,772
  • 8
  • 53
  • 86
  • Thank you. That is a possible solution. But is there a way to automatically do this? – GregRos Apr 15 '13 at 09:53
  • 2
    You still have to set up the project structure, but it's a one time operation. – Bas Apr 15 '13 at 09:56
  • Do you know if it's possible to make the extension work with partial classes, with only one of the projects having the file that provides the .NET 4.5 interface? – GregRos Apr 15 '13 at 10:04
  • 1
    Yes it's possible, but you still need the Project Linker. You can change the setting on the code file in one of the project to have 'build action: none' – Bas Apr 15 '13 at 10:13
  • I see. That is pretty sweet. It's going to solve so many problems. – GregRos Apr 15 '13 at 13:14
4

You can make two versions of the project file, targeting different framework versions. In this case I would place all the project files in the existing project directory.

In each project, you would define a symbol indicating the framework version (as needed), for example DOTNET45. You can do this under Properties - Build - Conditional Compilation Symbols

Then you can use the #if directive:

class MyClass<T> : IList<T>
#if DOTNET45
    , IReadOnlyList<T>
#endif
{
    // Your usual code

    #if DOTNET45

    // IReadOnlyList implementation

    #endif
}

This could get messy however. So alternatively, you could use partial classes:

partial class MyClass<T>
{
}

#if DOTNET45

partial class MyClass<T> : IReadOnlyList<int>
{
    // IReadOnlyList implementation
}

#endif

Obviously partial classes can also be divided over files, so potentially you could do without #if altogether, by only including this partial class file in the .NET 4.5 version of the project.

Thorarin
  • 47,289
  • 11
  • 75
  • 111
  • That is a great solution! I could use the extra partial class definition to store all the .NET 4.5 interface, including methods and things like that. – GregRos Apr 15 '13 at 10:06