2008-08-30 14 views
104

Tengo un método que toma objeto params [] tales como:Cómo pasar un solo objeto [] a un objeto params []

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

Cuando paso dos matrices de objetos a este método, que funciona bien :

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

Pero cuando pase un solo objeto [], no hace falta ser mi objeto [] como el primer parámetro, sino que toma su todos los elementos como si quisiera pasar uno por uno:

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

¿Cómo paso un único objeto [] como primer argumento a una matriz params?

Respuesta

82

Un encasillado simples se asegurará de que el compilador sabe lo que quiere decir en este caso.

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

Como una matriz es un subtipo de objeto, todo esto funciona. Aunque es una solución extraña, estoy de acuerdo.

+0

la forma en que params funciona parece innecesario, y el diseño de C# no es óptimo, dado lo que nos hemos acostumbrado en otros lenguajes. los params podrían haber sido hechos para aceptar solo un formulario, y se podría agregar una característica de propagación similar que beneficiaría a todo el lenguaje, no solo a este caso. por ejemplo, podríamos forzar que todas las llamadas de param sean Foo (obj [0], obj [1]), y luego tener un operador separado separado permitiendo Foo (... obj). – Lee

+0

se dio cuenta de que no había dejado claro que tengo un gran respeto por Anders Hejlsberg, es uno de los mejores diseñadores de idiomas del mundo. pero podemos pensar en mejoras para el trabajo de cualquiera con suficiente perspectiva, por lo tanto, tecnología. – Lee

3

Necesitas encapsular en otra tabla de objeto [], así:

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

Una opción es que se puede envolver en otra matriz:

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

un poco feo, pero desde cada elemento es una matriz, no puedes simplemente lanzarlo para que desaparezca el problema ... como si fuera Foo (elementos del objeto params), entonces podrías hacer:

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

Alternativamente, usted podría intentar definir otra instancia de Foo sobrecargado que toma sólo una única matriz:

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

El modificador de parámetro params proporciona a los llamantes una sintaxis de acceso directo para pasar múltiples argumentos a un método.Hay dos formas de llamar a un método con un parámetro params:

1) Llamar con una matriz del tipo de parámetro, en cuyo caso la palabra clave params no tiene efecto y la matriz se pasa directamente al método:

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

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

2) O, llamando con una extensa lista de argumentos, en cuyo caso el compilador se ajustará automáticamente la lista de argumentos en una matriz temporal y pasar a que el método:

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

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


el fin de pasar en una matriz de objetos a un método con un parámetro "params object[]", se puede:

1) crear una matriz envoltura manualmente y pase que directamente a la método, como se ha mencionado por lassevk:

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

2) O bien, el argumento a object, como mencionado por Adam, en cuyo caso el compilador creará la matriz contenedora para usted:

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


Sin embargo, si el objetivo del método es para procesar múltiples matrices de objetos, puede ser más fácil de declarar con un parámetro explícito "params object[][]". Esto permitirá pasar varias matrices como argumentos:

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

Editar: Raymond Chen describe este comportamiento y cómo se relaciona con la especificación de C# en a new post.

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

Esta es una solución de una línea que involucra a LINQ.

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