当前位置:  开发笔记 > 编程语言 > 正文

传递一个数组

如何解决《传递一个数组》经验,为你挑选了2个好方法。

在下面的示例代码中,当我不包含class约束时,为什么对genric类型的ArrayMethod调用失败

public interface IFoo { }
public interface IBar : IFoo { }

public class Test
{
    public void ClassConstraintTest() where T : class, IFoo
    {
        T[] variable = new T[0];
        ArrayMethod(variable);
    }

    public void GenericTest() where T : IFoo
    {
        T[] variable = new T[0];
        ArrayMethod(variable);  // Compilation error:  Can't convert T[] to IFoo[]
    }

    public void InheritanceTest()
    {
        IBar[] variable = new IBar[0];
        ArrayMethod(variable);
    }

    public void ArrayMethod(IFoo[] args) { }
}

Heinzi.. 9

这是因为数组协方差,即MySubtype[]作为子类型的事实MyType[],仅适用于引用类型.的class约束确保T是引用类型.

(请注意,回想起来,数组协方差被认为是一个坏主意.如果可以,例如,通过制作ArrayMethod泛型或使用IEnumerable替代,请尽量避免使用它.)



1> Heinzi..:

这是因为数组协方差,即MySubtype[]作为子类型的事实MyType[],仅适用于引用类型.的class约束确保T是引用类型.

(请注意,回想起来,数组协方差被认为是一个坏主意.如果可以,例如,通过制作ArrayMethod泛型或使用IEnumerable替代,请尽量避免使用它.)



2> Kyle Sletten..:

简而言之:只有当两个数组都是reference(class)类型时,数组协方差才有效.

要理解这一点,您必须了解不同类型数组的内存布局.在C#,我们有值阵列(int[],float[],DateTime[],任何用户定义的struct[]),其中每个事物被存储在数组内依次和参考阵列(object[],string[],任何用户定义的class[],interface[]delegate[])阵列和对象中,其中的引用是按顺序存储存储在数组中的任何位置.

当你请求该方法在任何T(没有: class约束)上工作时,你允许这两种类型的数组中的任何一种,但编译器知道任何int[](或任何其他值数组)不会以某种方式神奇地变为有效的事实IFoo[](或任何其他参考数组)并禁止转换.即使您的struct实现IFoo的原因不是IFoo[]参考数组,而且T[]将是一个值数组,这种情况也会发生.

但是,当您指定它T是引用类型(即class声明)时,现在可能它T[]是有效的,IFoo[]因为它们都是引用数组.因此编译器允许使用数组协方差规则的代码(声明您可以T[]IFoo[]需要的地方使用,因为T它是子类型IFoo).

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有