4

我希望能够将函数声明为

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,无法声明指向托管类型的指针。见下文“毫米”。我认为他是对的......这可能只是无法完成。

4

3 回答 3

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 继承,因此方法签名不匹配。

于 2009-02-19T00:50:52.233 回答
0
public void foo<T>(params T[] args) where T : struct {
}
public void SomeMethod() {
    foo(1, 2, 3, 4);
}

您不必输入泛型参数,因为编译器将从 foo 的第一个参数中获取类型。

于 2009-02-18T21:37:19.453 回答
-1

这会起作用:

    public static void foo(System.Array data)
    {

    }

    static void Main(string[] args)
    {
        foo(new int[10]);  
    }

它不强制数组是值类型的数组,但它会起作用。

于 2009-02-18T21:26:02.583 回答