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、マネージド型へのポインターを宣言できません。以下の「mm」を参照してください。私は彼が正しいと思う...おそらくそれは不可能だ.

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[])

結果のプログラムを実行することはできましたが、これがどのような副作用をもたらすかはわかりません。また、変更された関数を参照できたとしても、構造体はコンパイル後まで System.ValueType から継承されず、メソッド シグネチャが一致しないため、C# から呼び出すことはできません。

于 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 に答える