, IEnumerable , and ICollection ? The comments provided in the source c...">

What is TypeDependencyAttribute ("System.SZArrayHelper") for IList <T>, IEnumerable <T>, and ICollection <T>?

The comments provided in the source code for IList, IEnumerable, and ICollection say

Note that T[] : IList<T> , and we want to make sure that if you use IList<YourValueType> , we guarantee that YourValueType[] can be used without noise. Therefore, TypeDependencyAttribute on an SZArrayHelper . This is a special hack inside - see VM \ compile.cpp.

Why does IList<T> contain a dependency on SZArrayHelper ? I understand that SZArrayHelper is a CLR wrapper around an array that implements the IList<T> interface, but I cannot get a complete idea of ​​why the two are related to each other.

And how to ensure this YourValueType[] can be used without jitting.?

+5
source share
1 answer

This is a hack jit as indicated in your quote. When the VM discovers that TypeDependency on SZArrayHelper , it considers the class differently, allowing for more efficient code.

Look at the corresponding code in the virtual machine (note that I am using an older, public version here - not a real .NET VM):

An array call through IList (or IEnumerable or ICollection) must be handled specifically. These interfaces are "magical" (mainly because of the corresponding working set - they are created on demand within the company, although they are semantically static interfaces.)

Arrays are, firstly, a hack in .NET. When common interfaces were added, this was a small problem - for example, int[] is an Array , but it is also a special type and an array of int; this allowed arrays to be generic before real generic types were added.

Now let's see a specific example. You have int[] and you want to use it in LINQ. Since int[] implements IEnumerable<int> , it gives you the full LINQ power out of the box, and you can write something like this:

 var positiveNumbers = numbers.Where(i => i > 0); 

From the point of view of C # there are no problems. However, from the point of view of the internal components of a virtual machine, this is a big problem because int[] does not actually implement IEnumerable<int> ! Even after introducing generics into .NET (and C #), arrays are still processed in the old way.

A hacker must use SZArrayHelper to process any of these common methods. So, for example, Where calls GetEnumerator internally on an IEnumerable<int> . The VM finds out that you are trying to call GetEnumerator in the array and instead of actually sending GetEnumerator in the array instance, redirects the call to SZArrayHelper.GetEnumerator<int>() .

This is a huge hack - if you look at the link code for SZArrayHelper , you will find many warnings - for example, the GetEnumerator<int> method is an instance method, but this argument is actually an array (for example, int[] ), and not SZArrayHelper .

But this allows us to consider arrays as if they really implemented all these common interfaces - even if they do not :)

+9
source

Source: https://habr.com/ru/post/1235618/


All Articles