5
votes

Today I tested the following code in Visual Studio 2010 (.NET Framework version 4.0)

Type[] interfaces = typeof(int[]).GetInterfaces();

And I was shocked to find these two on the list:

System.Collections.Generic.IReadOnlyList`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

System.Collections.Generic.IReadOnlyCollection`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

I have used these two interfaces before in environments with framework 4.5+ installed, and according to the documentation, both of them were created for 4.5. This does not compile in my environment:

System.Collections.Generic.IReadOnlyList<int> list = new int[3];

The type or namespace name 'IReadOnlyCollection' does not exist in the namespace 'System.Collections.Generic' (are you missing an assembly reference?)

When I try this:

int[] array = new int[3];
Type iReadOnlyCollection = Type.GetType("System.Collections.Generic.IReadOnlyCollection`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
int count = (int)iReadOnlyCollection.GetProperty("Count").GetValue(array, null);

count equals 3, as expected. What is going on here?

Edit: I do not think framework 4.5 is installed on my machine:

Edit 2: Thanks @ScottChamberlain, it turns out I did have it installed.

2
new System.Collections.Generic.IReadOnlyList<int>(); is attempting to new up an interface; this will never compile, regardless of .NET version.Metro Smurf
@MetroSmurf thanks...durpMr Anderson
About your edit: see To find .NET Framework versions by viewing the registry (.NET Framework 4.5 and later) for how to check for versions later than 4.0.user743382

2 Answers

7
votes

.NET 4.5 is an in-place update for .NET 4. This means that while in visual studio you cannot reference IReadOnlyCollection<T> while targeting .NET 4, the runtime has this type available if you have the 4.5 update installed.

Try running your code in an environment where you don't have the .NET 4.5 update (i.e., just 4.0) and the code will not find the interface type. I.e., Type.GetType("System.Collections.Generic.IReadOnlyCollection`1... would return null, and typeof(int[]).GetInterfaces() will not contain the interfaces you mentioned.

4
votes

You're compiling for .NET 4.0, so 4.5-specific types aren't seen by the compiler.

You're running on .NET 4.5 or 4.6, so 4.5-specific types are seen by the runtime.

If you were expecting your application to run on .NET 4.0: you can't. .NET 4.5 and 4.6 are in-place upgrades. Once installed, your system no longer has .NET 4.0 on it. You can still run .NET 4.0 applications, as .NET 4.5 and 4.6 are largely backwards compatible, and that runtime environment will simply be used instead.