2008-08-30 76 views
104

我已經這需要一個方法params對象[]如:如何單個對象[]傳遞給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數組?

回答

82

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

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

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

+0

params的工作方式似乎是不必要的,而次優的c#設計,因爲我們已經習慣了其他語言。 params本來可以用來接受一種形式,並且可以增加一些可以使整個語言受益的擴展類功能,而不僅僅是這種情況。例如,我們可以強制所有參數調用都是Foo(obj [0],obj [1]),然後有一個允許Foo(... obj)的單獨傳播運算符。 – Lee 2017-12-15 19:21:39

3

你需要將其封裝到另一個對象[]數組,像這樣:

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

一種選擇是,你可以把它包裝成另一個數組:

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

類的醜陋,但由於每個項目是一個數組,你不能只是施加它使問題消失...如果它是Foo(params object items),那麼你可以這樣做:

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

或者,你可以嘗試定義富的另一重載實例,它只需在單個陣列:

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

參數修飾符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)或者,流延的參數object,如通過Adam提到的,在這種情況下,編譯器將創建爲您包裝陣列:

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

編輯:雷蒙德陳描述了這種行爲,以及它如何涉及a new post的C#規範。

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

這是一個涉及LINQ的單線解決方案。

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