es posible obtener la sintaxis que se mostró en la pregunta, pero usted tiene que participar en una cantidad bastante buena de la inteligencia con el fin de llegar allí.
Vamos a solucionar el problema un poco más concretamente. El punto clave aquí, creo, es la sintaxis. Queremos que este:
int intValue = GetData();
string stringValue = GetData();
DateTime[] dateTimeArrayValue = GetData();
Sin embargo, no queremos que esto funcione:
double doubleValue = GetData();
DateTime? nullableDateTimeValue = GetData();
Con el fin de lograr esto, tenemos que utilizar un objeto intermediario en el valor de retorno de GetData()
, cuya definición se ve así:
public class Data
{
public int IntData { get; set; }
public string StringData { get; set; }
public DateTime[] DataTimeArrayData { get; set; }
public MultiReturnValueHelper<int, string, DateTime[]> GetData()
{
return new MultiReturnValueHelper<int, string, DateTime[]>(
this.IntData,
this.StringData,
this.DataTimeArrayData);
}
}
Su puesta en práctica, por supuesto, sería muy diferente, pero esto va a hacer. Ahora definamos MultiReturnValueHelper
.
public class MultiReturnValueHelper<T1, T2, T3> : Tuple<T1, T2, T3>
{
internal MultiReturnValueHelper(T1 item1, T2 item2, T3 item3)
: base(item1, item2, item3)
{
}
public static implicit operator T1(MultiReturnValueHelper<T1, T2, T3> source)
{
return source.Item1;
}
public static implicit operator T2(MultiReturnValueHelper<T1, T2, T3> source)
{
return source.Item2;
}
public static implicit operator T3(MultiReturnValueHelper<T1, T2, T3> source)
{
return source.Item3;
}
}
Repita esta definición para T1
, T2
, T3
, etc para el caso genérico.
También puede enlazar el valor de retorno helper muy de cerca con la clase o el método que lo devuelve, lo que le permite crear el mismo tipo de efecto para los indexadores, donde puede obtener y asignar un conjunto discreto de tipos. Ahí es donde lo he encontrado más útil.
Otra aplicación es para permitir la sintaxis como la siguiente:
data["Hello"] = "World";
data["infamy"] = new DateTime(1941, 12, 7);
data[42] = "Life, the universe, and everything";
El mecanismo preciso para llevar a cabo esta sintaxis se deja como un ejercicio para el lector.
Para una solución más de propósito general a este problema (que es, creo, lo mismo que un problema unión discriminado), consulte my answer to that question.
charlieday, ¿podría darnos algunos detalles más sobre por qué quiere un método que puede devolver múltiples tipos de devolución? Me pregunto si la clase Convertir en el espacio de nombres del sistema podría ser un buen modelo a seguir. Tiene múltiples métodos de conversión de diferentes tipos de devolución, pero codifica el tipo de devolución en el nombre del método. P.ej. ToBoolean, ToByte, ToChar, etc. –
La razón se debe a que en su escenario, el tipo de información fluiría "en ambos sentidos". Un principio básico del diseño del lenguaje es que debe poder analizar el tipo de cada parte de una expresión de forma independiente. Queremos poder determinar el tipo de expresión de llamada independientemente de lo que se le asigna. La excepción a esta regla son las expresiones lambda; hacer que la información tipo "fluya en ambos sentidos" en expresiones lambda fue muy difícil. Consulte "métodos anónimos versus expresiones lambda" en mi blog para obtener más información. –
puede ver mi respuesta aquí http: // stackoverflow.com/questions/1366136/overloading-on-basis-de-return-type-only/14337184 # 14337184 –