2009-07-08 11 views
16

Estoy casi avergonzado de hacer esta pregunta, pero como programador de C desde hace mucho tiempo, siento que quizás no conozca la mejor manera de hacer esto en C#.¿Cuál es la mejor manera de devolver dos listas en C#?

Tengo una función de miembro que necesito devolver dos listas de un tipo personalizado (List<MyType>) y sé de antemano que siempre tendré un valor de retorno de solo dos de estas listas.

Las opciones obvias son:

public List<List<MyType>> ReturnTwoLists(); 

o

public void ReturnTwoLists(ref List<MyType> listOne, ref List<myType> listTwo); 

Ambos parecen ser no óptimo.

¿Alguna sugerencia sobre cómo mejorar esto?

La primera forma no deja en claro en la sintaxis que solo se devuelven 2 listas, y la segunda usa referencias en lugar de un valor de retorno, que parecen tan no C#.

Respuesta

31

En primer lugar, que probablemente debería ser out, no ref.

En segundo lugar, puede declarar y devolver un tipo que contenga las dos listas.

En tercer lugar, se puede declarar un genérico Tuple y devolver una instancia de esa:

class Tuple<T,U> { 
    public Tuple(T first, U second) { 
     First = first; 
     Second = second; 
    } 
    public T First { get; private set; } 
    public U Second { get; private set; } 
} 

static class Tuple { 
    // The following method is declared to take advantage of 
    // compiler type inference features and let us not specify 
    // the type parameters manually. 
    public static Tuple<T,U> Create<T,U>(T first, U second) { 
     return new Tuple<T,U>(first, second); 
    } 
} 

return Tuple.Create(firstList, secondList); 

Se puede extender esta idea para un número diferente de elementos.

+7

Solo un residuo ... .NET 4.0 tiene el tipo Tuple <>. –

+12

Veo que usaste T y U para especificar los elementos. Si tuvieras más de 2 tuplas, ¿elegirías T-U-V-W ... o T-U-P-L-E? :) –

+5

@Mark: no lo he pensado. ¡Antes de pensar en eso, pensaría en cambiar a F #! –

24

Volver esto:

public class MyTwoLists { 
    public List<MyType> ListOne {get;set;} 
    public List<MyType> ListTwo {get;set;} 
} 
0

¿Cree una estructura simple que contenga ambos y la devuelva como resultado de la función?

4

Su primera sugerencia no son dos listas. Es una lista de listas.

La segunda opción haría lo que usted desea, pero es posible que desee cambiarla para usar la palabra clave out en lugar de ref, de modo que las personas que llaman conocerán la intención de lo que está haciendo.

public void ReturnTwoLists(out List<MyType> listOne, out List<myType> listTwo); 
3

Usted tiene algunas opciones:

utilizar un par si las listas no tienen sentido en este orden:

public Pair<List<MyType>,List<MyType> ReturnTwoLists() 
{ 
     return new Pair(new List<MyType(), new List<MyType()); 
} 

Puede utilizar fuera o ref parámetros, como usted ha mencionado . Esta es una buena opción si una lista es más significativa que la otra.

Se puede usar un diccionario si el cliente va a conocer las claves, o quiere hacer el trabajo para mirar hacia arriba:

public Dictionary<string,List<MyType> ReturnTwoLists() 
{ 
     Dictionary<string,List<MyTpe>> d = new Dictionary<string,List<MyType>>(); 
     d.Add("FirstList",new List<MyType>()); 
     d.Add("SecondList",new List<MyType>()); 
     return new Dictionary()(new List<MyType(), new List<MyType()); 
} 

O, la solución más "correcta" en mis ojos, esté completo y consistencia, sería crear una clase de contenedor de datos simple para contener las dos listas.Esto le proporciona al consumidor valores de retorno fuertemente tipados, bien compilados estáticamente (lectura: intellisense) para trabajar. La clase se puede anidar justo al lado del método.

Cuestiones relacionadas