Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Referencing a .NET 3.5 DLL from a .NET 4.5.1 Application (EXE) uses .NET 4.5.1 Objects

Tags:

c#

.net

vb.net

So I have a DLL which is compiled using .NET 3.5. I am currently debugging the following line in this DLL:

in VB.NET:

 Dim result As IAsyncResult = CType(Cmd, SqlClient.SqlCommand).BeginExecuteNonQuery()

or (in C#)

IAsyncResult result = (SqlClient.SqlCommand) Cmd.BeginExecuteNonQuery()

I am referencing this DLL from a .NET 4.5.1 Compiled .EXE and when I look at the "result" object from the code above in the VS debugger I see:

Id = 1, Status = WaitingForActivation {1}, Method = "{null}", Result = "{Not yet computed}" 

This looks like a .NET 4.0 Task object (seeing the Property "Status"). Why am I seeing a .NET 4.x object in a .NET 3.5 DLL? How does mixing of .NET versions work?

like image 263
Denis Avatar asked Mar 18 '23 07:03

Denis


1 Answers

How does mixing of .NET versions work?

The basic thing you discovered here is that mixing .NET versions does not work. It can't, Microsoft used the opportunity at .NET 4.0 to re-engineer many of the standard .NET classes. Just as an example, the StringBuilder class was completely redesigned, now using ropes as the internal data structure to avoid getting long strings into the LOH. And the String class was changed, optimized to remove the unnecessary internal m_arrayLength field. Many more examples of this.

Mixing different string types inside a program cannot work, you couldn't set the v2.0 SqlCommand.CommandText property with a v4.0 string for example, the objects are entirely incompatible.

So that is not what Microsoft did, they solved it a different way. Your .NET 3.5 targeted assembly will say that it has a dependency on System.Data, version 2.0.0.0. The CLR recognizes this assembly, it will translate the reference and substitute it with the 4.0.0.0 assembly instead. This is completely automatic and there is no config to affect this translation.

It was Microsoft burden to ensure that the 4.0.0.0 version was a completely functional substitute for the 2.0.0.0 version. Not actually that hard to do, it goes wrong very infrequently. Usually only because they also took the 4.0 release as an opportunity to fix several 2.0 runtime bugs, the kind that apps could accidentally take a dependency on. Technically you do need to retest your app to ensure you didn't.

So this explains it, the debugger shows you the internals and reveals v4.0 details.

like image 160
Hans Passant Avatar answered Mar 20 '23 06:03

Hans Passant