将任何值类型的数组作为形式参数

时间:2009-02-18 15:52:07

标签: c# declaration value-type

我希望能够将函数声明为

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”。我认为他是对的......可能只是做不到。

3 个答案:

答案 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]);  
    }

它并不强制数组是值类型的数组,但它可以工作。