为什么不能System.Array的是一种约束?(Why can't System.Arra

2019-07-19 16:50发布

我工作的一个小项目有一些不同类型的数组(如double[] float[] int[]为了验证/测试/神智的目的,我打印出一些阵列控制台为我走所以我有一个看起来像下面的这些多种功能(简化这个例子 - 假设我只处理一维数组):

void Print(float[] a) // prints an array of floats
{
    for (int i = 0; i < a.Length; i++)
    {
        Console.Write(a[i]);
    }
}

void Print(double[] a) // prints an array of doubles
{
    for (int i = 0; i < a.Length; i++)
    {
        Console.Write(a[i]);
    }
}

我,在我无穷的智慧,以为可以通过简单地创建这些功能的通用版本,减少一些重复的代码。 所以我尝试这样做:

void Print<T>(T t) where T : Array
{
    for (int i = 0; i < t.Length; i++)
    {
        Console.Write(t.GetValue(i));
    }
}

智能感知不抱怨,但是编译器失败,一个很有趣的错误:

Constraint cannot be special class 'System.Array'

我看过一个解释(类似于Object或密封类,但都没有找到多少,除了一提的MSDN上 。任何人都可以向我解释为什么是这样的情况?为什么我不能指定类型约束System.Array

PS:虽然打字了这一点,我意识到,我可以完成我本来想更容易,像这样一个简单的函数:

void Print(System.Array a)
{
    for (int i = 0; i < a.Length; i++)
    {
        Console.Write(a.GetValue(i));
    }
}

这是为什么有在编译器阵列中一个特殊的规则?

Answer 1:

适当的语法做你想要的东西是这样的:

void Print<T>(T[] array)
{
    for (int i = 0; i < array.Length; i++)
    {
        Console.Write(array[i]);
    }
}


Answer 2:

如果采取这个问题从字面上看,这将是没用的,有一个Array的约束。 这是一样也没用有一个ValueType约束,因为它实际上不检查是否使用的值类型作为一般的参数,而是要传递的类型是否是分配给ValueType
所以,你可以通过连Array作为一般的参数,它的确定。

什么是真正有用的是有一个数组 contraint允许任何类型的派生自Array ,而不是Array本身:

void Print<TArr>(TArr t) where TArr : array //or [*] or other fancy syntax

其中T可以是[] [,][,,] [,,,]等等。 只有在非通用Array参数是,我们知道数组的元素类型。

解决这个另一种方法是创建一个定制的Array<T>用的隐式运算符重载类T[] T[,]T[,,]

编辑:
有没有办法,即使在CIL(目前)来实现这一点,因为int[,]Array没有任何接口或构造不同。 我们需要where T : Array but not Array itself contraint。



文章来源: Why can't System.Array be a type constraint?