26

I have a project that uses System.Runtime.Serialization assembly. I am using the type DataContractSerializer from that assembly, but I have a problem. There are two assemblies:

C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Runtime.Serialization.dll

C:\Windows\Microsoft.net\Framework\v4.0.30319\System.Runtime.Serialization.dll

Both of them have the same version - v4.0.30319. The first one have 429kb size, and the second one 1037kb. I used reflector to see the list of classes, and the first one doesn't have the class that I need (DataContractSerializerSettings). However, the second one does have it.

Why are there some big difference in size and classes for that assembly? Will it be ok, if I use the second one, instead of the first?

Community
  • 1
  • 1
Sergey Litvinov
  • 7,408
  • 5
  • 46
  • 67

1 Answers1

54

.NET version 4.0 made a big change in the way framework reference assemblies are done. Previously, the reference assembly was a simple copy of the runtime assembly, the one stored in the GAC. That however caused some painful problems. Notable is the WaitHandle.WaitOne(int) overload, it was added in the .NET 2.0 Service Pack 2 update (aka .NET 3.5). Programmers used it without noticing that it was an added method, the mscorlib assembly version number was still 2.0.0.0. But then discovered their program failed when running on an unpatched version of .NET 2.0. Very nasty kaboom, MissingMethodException without a hint why such a common method could be missing.

To prevent this kind of breakage, the .NET 4.0 reference assemblies are kept separate, in the "%programfiles%\Reference Assemblies" directory as you found out. And they are special assemblies, they only contain the metadata with all the IL stripped out. Which is why the assembly is so much smaller.

Microsoft now can improve the .NET 4 code and add public classes and methods without causing this kind of breakage. And have done so profusely, updates 4.01, 4.02 and 4.03 have shipped since the original 4.0 release.

The reason you are having trouble with the DataContractSerializerSetting class is thus easily explained, it just doesn't appear in the reference assembly. It got added, probably in one of those incremental updates. And you should not try, your program will break on a machine that doesn't have the update. You should wait until .NET 4.5, the version that added it to the reference assembly. You can invoke DLL Hell if you really want to.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks @Hans, your answer is very useful. However now I'm worried about this [question](http://stackoverflow.com/questions/9655362/localdb-deployment-on-client-pc) and the answer that was given to me. Could you give your opinion there on how to get this interim release 4.0.2 etc on client PCs? – Steve Mar 14 '12 at 12:47
  • 4
    As long as you consider using a beta version of a dbase engine then you might as well go whole-hog and also use the beta version of .NET 4.5. Hopefully your customer is willing to participate as well. – Hans Passant Mar 14 '12 at 12:54
  • To be concrete, how does (would) the metadata-only variant of the assembly help in the case of the added overload `WaitHandle.WaitOne(int)`? I can't understand that. If you leave out the new overload from the Service-Pack-1 version of the "reference" assembly (metadata-only assembly), how is the new overload useful at all? If you include the new overload in the new reference assembly, how will it make programmers aware that they use a feature from a Service Pack? I just don't get it. – Jeppe Stig Nielsen Oct 19 '13 at 00:33
  • The point is that you *don't* include the new overload in the reference assembly. So nobody can accidentally use it. And create a new set of reference assemblies with a different name. – Hans Passant Oct 19 '13 at 06:01
  • 3
    @HansPassant How do you know so much, and esp. all of this? This kind of information must privy to a very elite group, I suspect. How do I get to know about this kind of stuff? How do I become as good a programmer as you are? – Water Cooler v2 Feb 26 '15 at 09:42
  • 16
    Never assume anything, always ask "why", keep digging until you find out. Keep that up for 30 years. – Hans Passant Feb 26 '15 at 11:01
  • This explains the discrepancy I saw in `Exception.HResult`'s accessibility, which changed in .Net 4.5. Had to add `BindingFlags.Public` to my 4.0 code that accessed it through reflection, despite Visual 2010 and the 4.0 compiler still telling me it was private: If I got it right, Visual and Compiler used the 4.0 reference assembly while the run-time used the 4.5 one! – Medinoc Jan 12 '17 at 14:24
  • 1
    So where is the real assembly? – Wouter May 02 '20 at 16:38