简体   繁体   中英

What .NET Framework and C# version should I target with my class library?

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 possible to produce a backwards-compatible DLL or different DLLs for different versions? Or does Windows automatically update the .NET framework so I should just use the latest version? Any guidance appreciated!

Personally, I'd target .NET 2.0. This means, among other things:

  • No extension methods (there is a workaround though)
  • No linq

  • you CAN use lambda expressions

  • you CAN use the 'var' keyword

The thing is, you can use C# 3.x language features (the so-called syntactic sugar), but you can't use libraries that target C# 3.x (System.Core to name one, includes extension methods and linq).

I wouldn't try to support C# 1.x, as it's quite different from C# 2.x and higher. Besides, I expect most people who would use your library are people building new things, who wouldn't in their right minds use C# 1.x ;-)

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:

  • Separate Solution and Project files and for each of .NET 1.1, 2.0, and 3.5 SP1, but referencing the same source files.

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
  • We then have NAnt scripts which automate the production of a release for each .NET version. We happen to control all this through TeamCity, but we can trigger the NAnt scripts manually too.

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.

除非你需要使用3.0或3.5功能,否则我会保持2.0。

try this:

switch targetting mode to framework 2.0 (removing System.Core reference).

if it not compile, than try adding a reference to linqbridge.dll :

If not, then you should target 3.5 ;)

If I were to start a new project, I would always use the newest runtime! If 3.5 is available, why would I need to start a project in 2.0, or 1.0 unless I knew that there is something seriously wrong with the new version? New versions mean fixing old bugs and adding new features so this is good.

When it comes to upgrading old project to a new version, then you need to consider your gains and losses. If its worthed, upgrade it, if not stick with the old version.

Be careful thought because new tools might not support older versions. Though this is not the case with 2010 as it will support all version up to 2.0.

I vote for Erik van Brakel's answer. Also I would like to suggest that if you want to support 3.5 features like LINQ and Extension methods, you may create an additional library, say

MyLibrary.DLL

MyLibrary.LINQ.dll

thus using the same approach as MS did (when they left System.dll 2.0 version but added all new features into System.Core.dll)

我将使用包含核心功能的库来定位2.0版,并添加一个额外的目标库3.5,以根据您的核心库添加一些扩展方法。

从我的角度来看,如果你想要广泛的用户,你应该使用早期版本,1.1会很好,因为它可以在任何机器上运行.Net的版本。

It depends on what the dll is for. If it just has a generic C# logic that you would like to make available to others, then .net 2.0 is probably your best bet. However if it has anything to do with the newer features in .net like WPF, EF, WCF, silverlight, ect then it will need to be in the version of .net that supports that particular feature.

Personally, I would say write it in .net 3.5 only because making the jump from .net2.0 to .net3.5 is pretty painless because there is not many breaking changes unlike the jump from .net1.x to .net2.0. :)

I don't think anyone uses .Net 1.1 anymore. So unless you really want to use 3.5 features 2.0 should be fine. Also if you have control over who's going to actually use your library then it depends on them too. If they have the latest framework then you could use that.

Combined with using an approach like the one mentioned by Will Hughes, if you want the access / option to use newer features when available, during active development, use the latest framework. When ready to start making release candidates, set to the lowest framework, and then when issues arrive, steadily bump up the framework version and / or use the #ifdef approach to work out.

This solution works quite well. I just set up two different projects each with a unique "Project Properties->Build->Conditional compilation Symbols" and used in the code like this:

#if NET_4
            xmlReaderSettings.DtdProcessing = DtdProcessing.Ignore; 
#endif
#if NET_3_5
            xmlReaderSettings.ProhibitDtd = false;                
#endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM