C# 系统背后的秘密。阵列

C# 系统背后的秘密。阵列,c#,.net,C#,.net,我们知道System.Array是一个抽象类,我们在运行时使用的任何DataType[]都会以某种方式为我们创建一些具体的实现(虽然很模糊) 考虑以下代码段 int[] someInts = { 1, 2, 3, 4 }; IList<int> collection = someInts; collection.Clear(); 这怎么可能呢?我正在调用int[]上的Clear()方法,但是调用如何转到szarrayhelp.Clear。请注意,Clear是szarayHelper

我们知道
System.Array
是一个抽象类,我们在运行时使用的任何
DataType[]
都会以某种方式为我们创建一些具体的实现(虽然很模糊)

考虑以下代码段

int[] someInts = { 1, 2, 3, 4 };
IList<int> collection = someInts;
collection.Clear();
这怎么可能呢?我正在调用
int[]
上的
Clear()
方法,但是调用如何转到
szarrayhelp.Clear
。请注意,
Clear
szarayHelper
中的一个实例方法,定义如下

private void Clear<T>()
{
    throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
}
private void Clear()
{
抛出新的NotSupportedException(Environment.GetResourceString(“NotSupported\u ReadOnlyCollection”);
}
谁创建了“SZArrayHelper”的实例,并注意到Clear方法是私有的。我对正在发生的事情很困惑。如果创建了“SZArrayHelper”的实例并调用了
Clear
,那么执行此调用的helper方法应该位于“StackTrace”中。但事实并非如此

有人能解释一下幕后发生了什么吗

注:

  • int[]
    只是一个例子,你几乎可以用任何类型的数组来模拟它,而且不仅
    Clear
    method
    Add
    Contains
    等具有相同的行为

  • 我尝试使用reflector addin进行调试,这给了我相同的结果。调试器显示对
    szarayHelper.Clear()
    的直接调用

  • 谷歌让我想到了这一点。这有助于理解幕后正在发生的魔法,但仍有一些神秘之处


  • 您没有看到对该方法的任何调用,因为您自己正在调用它,这听起来可能很奇怪
    szarayHelper
    是一个围绕数组的CLR包装器,它实现了
    IList
    接口,有点像适配器模式

    从这个角度来看,
    collection.Clear
    直接调用
    szarayHelper.Clear
    ,是有意义的


    Hans Passant在这里很好地解释了这一点:

    私有类方法可以实现公共接口方法。数组类型实现了
    IList
    ,这一直困扰着我,因为它无法完成列表可以完成的基本任务,如添加项、删除项、清除自身等。我确信这样做是有原因的,但是我有几次被它抓住了。@JoeEnos-IList的对象在返回
    IsReadOnly=true
    (比如数组-
    ((IList)(new int[3])。IsReadOnly==true
    )时应该以这种方式运行。
    Array
    在运行时实现
    IList
    。显然,这个实现调用了
    szarayHelper.Clear()
    数组基本上是伏都教。因为它们早于泛型,但必须允许动态创建类型(即使在.NET1.0中),所以它们是使用技巧、黑客和花招实现的。我想你看到的基本上是这个骗局的实施细节。这一切都很有趣,但有时最好呆在幕后欣赏演出。无知是幸福;pI支持这个答案:)@HansPassant我想你知道CLR的每个角落,太好了。。非常感谢你。。在你支持这个答案之后,我只能接受这个答案:)@dcastro非常感谢你。有价值的链接。这就清楚了。我只是一个卑微的弟子^^
    private void Clear<T>()
    {
        throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
    }