Pregunta

Me pregunto cómo abordan otros desarrolladores este problema de obtener 2 o 3 respuestas de un método.

1) devolver un objeto []
2) devolver una clase personalizada
3) utilice una palabra clave out o ref en múltiples variables
4) escribir o tomar prestada (F#) una clase genérica Tuple<> simple
http://slideguitarist.blogspot.com/2008/02/whats-f-tuple.html

Estoy trabajando en un código que actualiza los datos.Del método que realiza la actualización, me gustaría pasar (1) la hora de inicio de la actualización y (2) la hora de finalización de la actualización.
En una fecha posterior, es posible que desee devolver un tercer valor.

¿Pensamientos?¿Alguna buena práctica de proyectos .NET de código abierto sobre este tema?

¿Fue útil?

Solución

Su pregunta apunta a la posibilidad de que devuelva más datos en el futuro, por lo que recomendaría implementar su propia clase para contener los datos.

Lo que esto significa es que la firma de su método seguirá siendo la misma, incluso si la representación interna del objeto que está pasando cambia para acomodar más datos. También es una buena práctica por razones de legibilidad y encapsulación.

Otros consejos

Depende completamente de cuáles sean los resultados. Si están relacionados entre sí, generalmente crearía una clase personalizada.

Si no están realmente relacionados, usaría un parámetro out o dividiría el método. Si un método quiere devolver tres elementos no relacionados, probablemente esté haciendo demasiado. La excepción a esto es cuando estás hablando a través de un límite de servicio web o algo más donde un & "; Más puro &"; API puede ser demasiado hablador.

Para dos, generalmente 4)

Más que eso, 2)

En cuanto a la arquitectura de código, siempre iría con una clase personalizada cuando necesito un cambio en una cantidad específica de variables. ¿Por qué? Simplemente porque una clase es en realidad un & Quot; blueprint & Quot; de un tipo de datos de uso frecuente, crear su propio tipo de datos, que en este caso es, lo ayudará a obtener una buena estructura y ayudar a otros a programar para su interfaz.

Personalmente, odio los parámetros / ref, así que prefiero no usar ese enfoque. Además, la mayoría de las veces, si necesita devolver más de un resultado, probablemente esté haciendo algo mal.

Si realmente es inevitable, probablemente será más feliz a la larga escribiendo una clase personalizada. Devolver una matriz es tentador, ya que es fácil y efectivo en el corto plazo, pero el uso de una clase le da la opción de cambiar el tipo de devolución en el futuro sin tener que preocuparse demasiado por causar problemas en el futuro. Imagine el potencial de una pesadilla de depuración si alguien intercambia el orden de dos elementos en la matriz que se devuelve ...

Utilizo si son solo 1 o 2 variables adicionales (por ejemplo, una función devuelve un valor bool que es el resultado importante real, pero también un parámetro largo como out para devolver cuánto tiempo se ejecutó la función, para fines de registro) .

Para cualquier cosa más complicada, generalmente creo una estructura / clase personalizada.

Creo que la forma más común en que un programador de C # haría esto sería envolver los elementos que desea devolver en una clase separada. Esto le proporcionaría la mayor flexibilidad en el futuro, en mi humilde opinión.

Depende. Para una API solo interna, generalmente elegiré la opción más fácil. En general eso está fuera.

Para una API pública, una clase personalizada generalmente tiene más sentido, pero si es algo bastante primitivo, o el resultado natural de la función es un valor booleano (como *. TryParse), me quedaré con un parámetro fuera. También puede hacer una clase personalizada con un elenco implícito para bool, pero eso suele ser extraño.

Para su situación particular, una clase DateRange inmutable simple me parece más apropiada. Puede agregar fácilmente ese nuevo valor sin molestar a los usuarios existentes.

Si desea devolver las horas de inicio y finalización de la actualización, eso sugiere una posible clase o estructura, quizás llamada DataRefreshResults. Si su posible tercer valor también está relacionado con la actualización, entonces podría agregarse. Recuerde, una estructura siempre se pasa por valor, por lo que no se debe recolectar basura en el montón.

Algunas personas usan KeyValuePair para dos valores.Sin embargo, no es genial porque simplemente etiqueta las dos cosas como Key y Value.No muy descriptivo.También se beneficiaría seriamente si se agregara esto:

public static class KeyValuePair
{
    public static KeyValuePair<K, V> Make(K k, V v) 
    { 
        return new KeyValuePair<K, V>(k, v); 
    }
}

Le evita tener que especificar los tipos cuando crea uno.Los métodos genéricos pueden inferir tipos, los constructores de clases genéricas no.

Para su escenario, es posible que desee definir la clase genérica Rango {T} (con comprobaciones de la validez del rango).

Si el método es privado, generalmente uso tuplas de mi biblioteca auxiliar . Los métodos públicos o protegidos generalmente siempre merecen ser separados.

Devuelve un tipo personalizado, pero no use una clase, use una estructura: sin sobrecarga de asignación de memoria / recolección de basura significa que no hay inconvenientes.

Si 2, un par.

Si hay más de 2 por clase.

Otra solución es devolver un diccionario de referencias de objetos con nombre. Para mí, esto es bastante equivalente a usar una clase de retorno personalizada, pero sin el desorden. (Y utilizando RTTI y la reflexión es tan seguro para los tipos de letra como cualquier otra solución, aunque de forma dinámica).

Depende del tipo y el significado de los resultados, así como de si el método es privado o no.

Para métodos privados, generalmente uso una Tupla, de mi biblioteca de clases.

Para métodos públicos / protegidos / internos (es decir, no privados), utilizo el parámetro out o una clase personalizada.

Por ejemplo, si estoy implementando el patrón TryXYZ, donde tienes un método XYZ que arroja una excepción en caso de falla y un método TryXYZ que devuelve Boolean, TryXYZ usará un parámetro out.

Si los resultados están orientados a la secuencia (es decir, devolver 3 clientes que deberían procesarse), normalmente devolveré algún tipo de colección.

Aparte de eso, generalmente solo uso una clase personalizada.

Si un método genera dos o tres valores relacionados, los agruparía en un tipo. Si los valores no están relacionados, lo más probable es que el método esté haciendo demasiado y lo refactorizaría en una serie de métodos más simples.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top