C# ILST的TypeDependencyAttribute(“System.szarayHelper”)的用途<;T>;,IEnumerable<;T>;和ICollection<;T>;?
IList、IEnumerable和ICollection中提供的评论说 请注意C# ILST的TypeDependencyAttribute(“System.szarayHelper”)的用途<;T>;,IEnumerable<;T>;和ICollection<;T>;?,c#,.net,C#,.net,IList、IEnumerable和ICollection中提供的评论说 请注意T[]:IList,我们希望确保 IList,我们确保可以使用YourValueType[] 没有紧张。因此,szarayHelper上的TypeDependencyAttribute。 这是一种特殊的内部攻击-请参阅VM\compile.cpp 为什么IList包含对szarayHelper的依赖关系?。我知道SZArrayHelper是实现IList接口的数组周围的CLR包装器,但我不完全了解这两个接口绑定在一起
T[]:IList
,我们希望确保
IList
,我们确保可以使用YourValueType[]
没有紧张。因此,szarayHelper
上的TypeDependencyAttribute
。
这是一种特殊的内部攻击-请参阅VM\compile.cpp
为什么IList
包含对szarayHelper
的依赖关系?。我知道SZArrayHelper
是实现IList
接口的数组周围的CLR包装器,但我不完全了解这两个接口绑定在一起的原因
它如何确保
YourValueType[]
可以在不使用JIT的情况下使用呢?正如您在报价中所指出的,这是JIT中的一个漏洞。当VM发现szarayHelper
上存在TypeDependency
时,它会以不同的方式对待该类,从而允许使用更高效的代码
查看VM中的相关代码(请注意,我在这里使用的是较旧的公共版本,而不是实际的.NET VM):
必须专门处理通过IList(或IEnumerable或ICollection)对数组的调用。
这些接口是“神奇的”(主要是由于相关的工作集——它们是根据内部需求创建的)
即使在语义上,这些都是静态接口。)
首先,数组在.NET中有点像黑客。当添加通用接口时,这带来了一点问题-例如,int[]
是一个数组
,但它也是一个特殊类型,并且是int数组;这允许数组在添加真正的泛型类型之前是泛型的
现在,让我们看一个具体的例子。您有一个int[]
,并且希望在LINQ中使用它。由于int[]
实现了IEnumerable
,因此它为您提供了现成的LINQ的全部功能,您可以编写如下内容:
var positiveNumbers = numbers.Where(i => i > 0);
从C#的观点来看,没有问题。然而,从VM的内部来看,这是一个大问题,因为int[]
实际上并没有实现IEnumerable
!即使在将泛型引入.NET(和C#)之后,数组仍然以旧的方式处理
黑客是使用szarayHelper
来处理这些通用方法中的任何一种。例如,Where
在IEnumerable
上内部调用GetEnumerator
。VM发现您试图在数组上调用GetEnumerator
,而不是在数组实例上实际调度GetEnumerator
,它将调用重定向到szarayHelper.GetEnumerator()
这是一个巨大的漏洞-如果你查看szarayHelper
的参考代码,你会发现大量警告-例如,GetEnumerator
方法是一个实例方法,但它是这个参数实际上是数组(例如int[]
),而不是szarayHelper
但它允许我们将数组视为它们确实实现了所有这些通用接口——尽管它们没有:)可能是因为99.9%的集合在某种程度上使用数组进行存储,因此要求这种依赖性是合理的。这是你的问题还是你只是好奇?@DStandley:好奇。。但是,它又如何确保您的ValueType[]可以在没有jitting的情况下使用呢?这并不是关于YourValueType[]
本身的问题。它是关于在转换到相应的通用接口时使用它int[]
实际上并没有实现IEnumerable.GetEnumerator
,即使它看起来好像实现了-实际的实现在那个神秘的szarayHelper
类中。