Frage

Ich habe eine Methode, die params object[] akzeptiert, wie zum Beispiel:

void Foo(params object[] items)
{
    Console.WriteLine(items[0]);
}

Wenn ich zwei Objektarrays an diese Methode übergebe, funktioniert es einwandfrei:

Foo(new object[]{ (object)"1", (object)"2" }, new object[]{ (object)"3", (object)"4" } );
// Output: System.Object[]

Aber wenn ich ein einzelnes Objekt[] übergebe, nimmt es nicht mein Objekt[] als ersten Parameter, sondern alle Elemente, als ob ich sie einzeln übergeben wollte:

Foo(new object[]{ (object)"1", (object)"2" });
// Output: 1, expected: System.Object[]

Wie übergebe ich ein einzelnes Objekt[] als erstes Argument an ein Parameter-Array?

War es hilfreich?

Lösung

Eine einfache Typumwandlung stellt sicher, dass der Compiler weiß, was Sie in diesem Fall meinen.

Foo((object)new object[]{ (object)"1", (object)"2" }));

Da ein Array ein Subtyp eines Objekts ist, funktioniert das alles.Allerdings eine etwas seltsame Lösung, da stimme ich zu.

Andere Tipps

Der params Der Parametermodifikator gibt Aufrufern eine Abkürzungssyntax für die Übergabe mehrerer Argumente an eine Methode.Es gibt zwei Möglichkeiten, eine Methode mit a aufzurufen params Parameter:

1) Aufruf mit einem Array vom Parametertyp, in diesem Fall der params Das Schlüsselwort hat keine Auswirkung und das Array wird direkt an die Methode übergeben:

object[] array = new[] { "1", "2" };

// Foo receives the 'array' argument directly.
Foo( array );

2) Oder Aufrufen mit einer erweiterten Liste von Argumenten. In diesem Fall verpackt der Compiler die Liste der Argumente automatisch in ein temporäres Array und übergibt dieses an die Methode:

// Foo receives a temporary array containing the list of arguments.
Foo( "1", "2" );

// This is equivalent to:
object[] temp = new[] { "1", "2" );
Foo( temp );


Um ein Objektarray an eine Methode mit einem „ zu übergebenparams object[]"-Parameter können Sie entweder:

1) Erstellen Sie manuell ein Wrapper-Array und übergeben Sie es direkt an die Methode, wie von erwähnt lassevk:

Foo( new object[] { array } );  // Equivalent to calling convention 1.

2) Oder werfen Sie das Argument auf object, wie erwähnt von Adam, in diesem Fall erstellt der Compiler das Wrapper-Array für Sie:

Foo( (object)array );  // Equivalent to calling convention 2.


Wenn das Ziel der Methode jedoch darin besteht, mehrere Objektarrays zu verarbeiten, ist es möglicherweise einfacher, sie mit einem expliziten „ zu deklarieren.params object[][]" Parameter.Dies würde es Ihnen ermöglichen, mehrere Arrays als Argumente zu übergeben:

void Foo( params object[][] arrays ) {
  foreach( object[] array in arrays ) {
    // process array
  }
}

...
Foo( new[] { "1", "2" }, new[] { "3", "4" } );

// Equivalent to:
object[][] arrays = new[] {
  new[] { "1", "2" },
  new[] { "3", "4" }
};
Foo( arrays );

Bearbeiten: Raymond Chen beschreibt dieses Verhalten und seinen Zusammenhang mit der C#-Spezifikation in ein neuer Beitrag.

Dies ist eine einzeilige Lösung mit LINQ.

var elements = new String[] { "1", "2", "3" };
Foo(elements.Cast<object>().ToArray())

Sie müssen es in ein anderes Objekt[]-Array kapseln, etwa so:

Foo(new Object[] { new object[]{ (object)"1", (object)"2" }});

Eine Möglichkeit besteht darin, es in ein anderes Array einzuschließen:

Foo(new object[]{ new object[]{ (object)"1", (object)"2" } });

Irgendwie hässlich, aber da jedes Element ein Array ist, kann man es nicht einfach umwandeln, um das Problem zu lösen ...Wenn es beispielsweise Foo(params object items) wäre, könnten Sie einfach Folgendes tun:

Foo((object) new object[]{ (object)"1", (object)"2" });

Alternativ könnten Sie versuchen, eine weitere überladene Instanz von Foo zu definieren, die nur ein einzelnes Array benötigt:

void Foo(object[] item)
{
    // Somehow don't duplicate Foo(object[]) and
    // Foo(params object[]) without making an infinite
    // recursive call... maybe something like
    // FooImpl(params object[] items) and then this
    // could invoke it via:
    // FooImpl(new object[] { item });
}
new[] { (object) 0, (object) null, (object) false }

Eine andere Möglichkeit, dieses Problem zu lösen (es ist keine so gute Praxis, sieht aber schön aus):

static class Helper
{
    public static object AsSingleParam(this object[] arg)
    {
       return (object)arg;
    }
}

Verwendung:

f(new object[] { 1, 2, 3 }.AsSingleParam());
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top