C# 为什么可以';数组是否是类型约束?
我正在做一个小项目,使用几种不同类型的数组(例如,C# 为什么可以';数组是否是类型约束?,c#,.net,arrays,compiler-errors,generic-constraints,C#,.net,Arrays,Compiler Errors,Generic Constraints,我正在做一个小项目,使用几种不同类型的数组(例如,double[],float[],int[]。出于验证/测试/健全的目的,我正在将其中一些数组打印到控制台上。因此,我有多个如下所示的函数(本例简化-假设我只处理一维数组): 这就是编译器中对数组有特殊规则的原因吗?执行所需操作的适当语法如下: void Print<T>(T[] array) { for (int i = 0; i < array.Length; i++) { Console.W
double[]
,float[]
,int[]
。出于验证/测试/健全的目的,我正在将其中一些数组打印到控制台上。因此,我有多个如下所示的函数(本例简化-假设我只处理一维数组):
这就是编译器中对数组有特殊规则的原因吗?执行所需操作的适当语法如下:
void Print<T>(T[] array)
{
for (int i = 0; i < array.Length; i++)
{
Console.Write(array[i]);
}
}
void打印(T[]数组)
{
for(int i=0;i
如果从字面上理解这个问题,则使用数组
约束是没有用的。这与使用值类型
约束是一样的,因为它实际上并不检查是否将值类型用作泛型参数,而是检查您传递的类型是否可分配给值类型
因此,您可以将偶数
Array
作为泛型参数传递,这样就可以了
实际上有用的是使用数组约束,允许从数组
派生的任何类型,但不允许从数组
本身派生:
void Print<TArr>(TArr t) where TArr : array //or [*] or other fancy syntax
void Print(TArr t),其中TArr:array//或[*]或其他奇特语法
其中T
可以是[]
,[,]
,[,]
,[,,,]
,等等。非泛型数组的唯一参数是我们知道数组的元素类型
另一种解决方法是创建一个自定义的数组
类,其中隐式运算符重载为T[]
,T[,]
,T[,]
等
编辑:
即使在CIL(目前)中也无法实现这一点,因为int[,]
和数组
在任何接口或构造函数中都没有区别。我们需要其中t:Array而不是Array本身
约束。是有意义的,但我仍然好奇为什么不能有数组
的基类类型约束……另外,出于好奇,这与使用数组
类型的参数不同吗?如果我使用数组
,是否会出现一些装箱问题?@vlad没有装箱问题,因为数组是引用类型,而不是值类型,尽管从数组中获取的对象与类型化数组不同。这也不一样,因为数组
也可以是2、3或N维数组,或者没有0索引的数组。还有有道理。说清楚一点,你是说我试图写的东西是编译器不允许的,因为正确的语法是你发布的?也就是说,所有可以用完成的事情,其中T:Array
都可以在参数列表中完成?@vlad你应该使用这种语法,或者只是在非泛型中传递数组c方法,如果您不知道传入的数组的维度,或者正在处理1(或任何非零)索引数组。这并不是毫无用处的。如果不是因为禁止,您可以编写copyanderReversaraySegment(t dest,t source,int start,int length)其中T:System.Array
并让它接受源或目标中的一个或两个都是System.Array
的调用,但仍然拒绝source
和dest
是不兼容数组类型的调用。事实上,我认为没有办法允许System.Array
作为r其中一个没有任何该类型导数的参数也被认为是可接受的。因此,到目前为止还没有实际的答案。
void Print(System.Array a)
{
for (int i = 0; i < a.Length; i++)
{
Console.Write(a.GetValue(i));
}
}
void Print<T>(T[] array)
{
for (int i = 0; i < array.Length; i++)
{
Console.Write(array[i]);
}
}
void Print<TArr>(TArr t) where TArr : array //or [*] or other fancy syntax