Frage

Ich möchte in der Lage sein, eine Funktion wie

zu erklären,
void foo(<any value type>[] data){}

in C # 2.0. Wenn ich erkläre es als

void foo(ValueType[] data){}

es kompiliert, aber dann die Elemente in Daten [] behandelt werden, als ob sie von object abgeleitet sind, z.B. Ich kann nicht sagen, so etwas wie

fixed (void* pData = data){}

würde Ich mag die Lücke zu vermeiden, nehmen * als Parameter - Ich möchte nur in der Lage sein, jeden beliebigen Wert-Typ-Array zu akzeptieren und dann tut unmanaged Dinge es

.

ETA: Auch dies hat das gleiche Problem:

public static unsafe void foo<T>(T[] data) where T:struct{
  fixed(void *p = data){}
}

, falls Sie sich wundern. Feste schlägt fehl, da es als verwaltetes Art behandelt wird - CS0208, nicht einen Zeiger auf einen verwalteten Typ deklarieren. Siehe „mm“ weiter unten. Ich glaube, er ist richtig ... es wohl einfach nicht durchgeführt werden.

War es hilfreich?

Lösung

Ich glaube nicht, das möglich ist, mit C #. Structs erben nicht (aber lose) von System.ValueType bis nach der Zeit zu kompilieren, so dass Sie nicht Foo-Methode Signatur über Polymorphismus mithalten können. Generika sind auch gemäß der Sprachspezifikation:

  

"Ein nicht verwalteter-Typ ist jede Art, die kein Referenz-Typ ist, ein Typ-Parameter , oder ein generischer Struktur-Typ und   enthält keine Felder, deren Typ nicht ein nicht verwalteter-Typ. "

Also, warum Sie nicht die Adresse von T erfolgen können [], unabhängig von der Struktur Einschränkung.

Sie könnten einen Strukturtyp deklarieren (sagen wir, Bar) als Argument für Foo, den Code kompilieren, und die Methodensignatur auf der Ebene IL ändern:

.method private hidebysig static void Foo(valuetype [mscorlib]System.ValueType[] args) cil managed

Und dann der Anruf auch:

IL_0020: call void ConsoleApplication1.Program::Foo(valuetype [mscorlib]System.ValueType[])

Während ich konnte das resultierende Programm laufen zu lassen, weiß ich nicht, welche Art von Nebenwirkungen dies hat. Auch wenn Sie die geänderte Funktion verweisen könnten, würden Sie nicht in der Lage sein, es von C # zu nennen, weil wieder structs von System.ValueType erbt erst nach der Kompilierung, so dass die Methodensignatur würde nicht überein.

Andere Tipps

public void foo<T>(params T[] args) where T : struct {
}
public void SomeMethod() {
    foo(1, 2, 3, 4);
}

Sie sollten nicht den generischen Parameter eingeben müssen, da der Compiler auf dem Typ aus dem ersten Parameter von foo abholt.

Das würde funktionieren:

    public static void foo(System.Array data)
    {

    }

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

Es erzwingt nicht, dass das Array ist ein Array von Werttypen, aber es funktionieren würde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top