将任意值类型的数组作为形参
我希望能够像
void foo(<any value type>[] data){}
C# 2.0 中那样声明一个函数。 如果我在
void foo(ValueType[] data){}
编译时声明它,但 data[] 中的元素会被视为派生自 object
,例如,我不能说类似“
fixed (void* pData = data){}
我想避免采用void* 作为参数——我只是希望能够接受任何值类型数组,然后对其执行非托管操作。
ETA:另外,这也有同样的问题:
public static unsafe void foo<T>(T[] data) where T:struct{
fixed(void *p = data){}
}
如果你想知道的话。 修复失败,因为它被视为托管类型 - CS0208,无法声明指向托管类型的指针。 参见下面的“毫米”。 我认为他是对的...这可能只是无法完成。
I would like to be able to declare a function as
void foo(<any value type>[] data){}
in C# 2.0. If I declare it as
void foo(ValueType[] data){}
it compiles, but then the elements in data[] are treated as though they're derived from object
, e.g. I can't say something like
fixed (void* pData = data){}
I'd like to avoid taking the void* as the parameter -- I just want to be able to accept any value-type array and then do unmanaged things to it.
ETA: Also, this has the same problem:
public static unsafe void foo<T>(T[] data) where T:struct{
fixed(void *p = data){}
}
in case you were wondering. Fixed fails because it's treated as a managed type -- CS0208, cannot declare a pointer to a managed type. See "mm" below. I think he's right... it probably just can't be done.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为使用 C# 不可能做到这一点。 直到编译时间之后,结构才会从 System.ValueType 继承(无论多么松散),因此您无法通过多态性匹配 Foo 的方法签名。 泛型也根据语言规范被淘汰:
因此,无论结构约束如何,您都无法获取 T[] 的地址。
您可以声明一个结构类型(例如 Bar)作为 Foo 的参数,编译代码,并在 IL 级别更改方法签名:
.method private hidebysig static void Foo(valuetype [mscorlib]System.ValueType[] args) cil Managed
然后也是调用:
< code>IL_0020: call void ConsoleApplication1.Program::Foo(valuetype [mscorlib]System.ValueType[])
虽然我能够运行生成的程序,但我也不知道这会产生什么样的副作用。 ,即使您可以引用修改后的函数,您也无法从 C# 调用它,因为在编译之前结构不会从 System.ValueType 继承,因此方法签名不匹配。
I don't think this is possible using C#. Structs do not inherit (however loosely) from System.ValueType until after compile time so you can't match Foo's method signature via polymorphism. Generics are also out according to the language specification:
So that's why you can't take the address of T[] regardless of the struct constraint.
You could declare a struct type (say, Bar) as the argument to Foo, compile the code, and change the method signature at the IL level:
.method private hidebysig static void Foo(valuetype [mscorlib]System.ValueType[] args) cil managed
And then the call as well:
IL_0020: call void ConsoleApplication1.Program::Foo(valuetype [mscorlib]System.ValueType[])
While I was able to run the resulting program I don't know what kind of side effects this has. Also, even if you could reference the modified function you wouldn't be able to call it from C# because again structs don't inherit from System.ValueType until after compilation so the method signature wouldn't match.
您不必输入泛型参数,因为编译器将从 foo 的第一个参数中获取类型。
You shouldn't have to enter the generic parameter because the compiler will pick up on the type from the first parameter of foo.
这是可行的:
它不会强制该数组是值类型的数组,但它会起作用。
This would work:
It doesn't enforce that the array is an array of value types, but it would work.