c# - usage - vb net control




如何將單個對象[]傳遞給params對象 (5)

我有一個方法,它採用PARAMS對象[],如:

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

當我將兩個對像數組傳遞給此方法時,它工作正常:

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

但是,當我傳遞一個單獨的對象[]時,它不會將我的對象[]作為第一個參數,而是將所有元素都像我想要的一樣逐一傳遞給它們:

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

如何將單個對象[]作為第一個參數傳遞給params數組?


params參數修飾符為調用者提供了將多個參數傳遞給方法的快捷語法。 有兩種方法可以用params參數調用一個方法:

1)使用參數類型的數組調用,在這種情況下, params關鍵字不起作用,數組直接傳遞給方法:

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

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

2)或者,用擴展的參數列表調用,在這種情況下,編譯器會自動將參數列表包裝在臨時數組中,並將其傳遞給方法:

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

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


為了將對像數組傳遞給帶有“ params object[] ”參數的方法,您可以:

1)手動創建一個包裝數組,並將其直接傳遞給方法,如lassevk

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

2)或者,如Adam提到的那樣,將參數強制轉換為object ,在這種情況下,編譯器將為您創建包裝器數組:

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


但是,如果該方法的目標是處理多個對像數組,則可以使用明確的“ params object[][] ”參數來聲明它。 這將允許您傳遞多個數組作為參數:

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 );

編輯: Raymond Chen在一篇新文章中描述了這種行為以及它與C#規範的關係


一個簡單的類型轉換將確保編譯器在這種情況下知道你的意思。

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

由於數組是一個對象的子類型,所以這一切都可以實現。 雖然有點奇怪的解決方案,我會同意。


您需要將其封裝到另一個對象[]數組中,如下所示:

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

解決這個問題的另一種方法(這不是很好的做法,但看起來很美):

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

用法:

f(new object[] { 1, 2, 3 }.AsSingleParam());

new[] { (object) 0, (object) null, (object) false }




arrays