我希望能够将函数声明为
void foo(<any value type>[] data){}
在C#2.0中。如果我将其声明为
void foo(ValueType[] data){}
它编译,但是数据[]中的元素被视为它们来自object
,例如我不能说像
fixed (void* pData = data){}
我想避免将void *作为参数 - 我只是希望能够接受任何值类型数组,然后对它进行非托管操作。
ETA:此外,这也存在同样的问题:
public static unsafe void foo<T>(T[] data) where T:struct{
fixed(void *p = data){}
}
万一你想知道。修复失败,因为它被视为托管类型 - CS0208,无法声明指向托管类型的指针。见下面的“mm”。我认为他是对的......可能只是做不到。
答案 0 :(得分:3)
我不认为使用C#是可行的。从编译时开始,结构不会从System.ValueType继承(但是松散),因此您无法通过多态与Foo的方法签名匹配。根据语言规范,泛型也出来了:
“非托管类型是任何不是引用类型,类型参数或通用结构类型的类型, 不包含类型不是非托管类型的字段。“
因此,无论结构约束如何,都无法获取T []的地址。
您可以将结构类型(例如,Bar)声明为Foo的参数,编译代码,并在IL级别更改方法签名:
.method private hidebysig static void Foo(valuetype [mscorlib]System.ValueType[] args) cil managed
然后是电话:
IL_0020: call void ConsoleApplication1.Program::Foo(valuetype [mscorlib]System.ValueType[])
虽然我能够运行生成的程序,但我不知道它有什么样的副作用。此外,即使您可以引用修改后的函数,也无法从C#调用它,因为在编译之后,结构体不再继承System.ValueType,因此方法签名不匹配。
答案 1 :(得分:0)
public void foo<T>(params T[] args) where T : struct {
}
public void SomeMethod() {
foo(1, 2, 3, 4);
}
您不必输入泛型参数,因为编译器将从foo的第一个参数中获取类型。
答案 2 :(得分:-1)
这样可行:
public static void foo(System.Array data)
{
}
static void Main(string[] args)
{
foo(new int[10]);
}
它并不强制数组是值类型的数组,但它可以工作。