Sé que esto es una vieja pregunta, pero si todo lo que queremos hacer es algo tan sencillo como imprimir esos tipos out, se puede hacer esto con mucha facilidad y sin tupla o nada extra usando 'dinámico':
private static void PrintTypes(params dynamic[] args)
{
foreach (var arg in args)
{
Console.WriteLine(arg.GetType());
}
}
static void Main(string[] args)
{
PrintTypes(1,1.0,"hello");
Console.ReadKey();
}
imprimirá "System.Int32", "System.Double", "System.String"
Si desea realizar alguna acción en estas cosas, por lo que sé, tiene dos opciones. Una es confiar en el programador para que estos tipos puedan realizar una acción compatible, por ejemplo, si quiere hacer un método para Sumar cualquier cantidad de parámetros. Se puede escribir un método como el siguiente dicho cómo desea recibir el resultado y el único requisito que supongo sería que la operación + trabaja entre estos tipos:
private static void AddToFirst<T>(ref T first, params dynamic[] args)
{
foreach (var arg in args)
{
first += arg;
}
}
static void Main(string[] args)
{
int x = 0;
AddToFirst(ref x,1,1.5,2.0,3.5,2);
Console.WriteLine(x);
double y = 0;
AddToFirst(ref y, 1, 1.5, 2.0, 3.5, 2);
Console.WriteLine(y);
Console.ReadKey();
}
Con esto, la salida de la primera línea haría ser "9" porque se agrega a un int, y la segunda línea sería "10" porque los .5s no se redondearon, agregando como un doble. El problema con este código es que si pasa algún tipo incompatible en la lista, tendrá un error porque los tipos no se pueden agregar juntos, y no verá ese error en tiempo de compilación, solo en el tiempo de ejecución.
Por lo tanto, dependiendo de su caso de uso, podría haber otra opción y es por eso que dije que al principio había dos opciones. Suponiendo que conozca las opciones para los posibles tipos, podría hacer una interfaz o clase abstracta y hacer que todos esos tipos implementen la interfaz. Por ejemplo, lo siguiente. Lo siento, esto es un poco loco.Y probablemente puede ser simplfied.
public interface Applyable<T>
{
void Apply(T input);
T GetValue();
}
public abstract class Convertable<T>
{
public dynamic value { get; set; }
public Convertable(dynamic value)
{
this.value = value;
}
public abstract T GetConvertedValue();
}
public class IntableInt : Convertable<int>, Applyable<int>
{
public IntableInt(int value) : base(value) {}
public override int GetConvertedValue()
{
return value;
}
public void Apply(int input)
{
value += input;
}
public int GetValue()
{
return value;
}
}
public class IntableDouble : Convertable<int>
{
public IntableDouble(double value) : base(value) {}
public override int GetConvertedValue()
{
return (int) value;
}
}
public class IntableString : Convertable<int>
{
public IntableString(string value) : base(value) {}
public override int GetConvertedValue()
{
// If it can't be parsed return zero
int result;
return int.TryParse(value, out result) ? result : 0;
}
}
private static void ApplyToFirst<TResult>(ref Applyable<TResult> first, params Convertable<TResult>[] args)
{
foreach (var arg in args)
{
first.Apply(arg.GetConvertedValue());
}
}
static void Main(string[] args)
{
Applyable<int> result = new IntableInt(0);
IntableInt myInt = new IntableInt(1);
IntableDouble myDouble1 = new IntableDouble(1.5);
IntableDouble myDouble2 = new IntableDouble(2.0);
IntableDouble myDouble3 = new IntableDouble(3.5);
IntableString myString = new IntableString("2");
ApplyToFirst(ref result, myInt, myDouble1, myDouble2, myDouble3, myString);
Console.WriteLine(result.GetValue());
Console.ReadKey();
}
salida será "9" el mismo que el código original Int, excepto los únicos valores que realmente puede pasar como parámetros son cosas que en realidad se han definido y que sabemos que va a trabajar y no causar ningún error. Por supuesto, tendrías que hacer nuevas clases, es decir, DoubleableInt, DoubleableString, etc. para volver a crear el segundo resultado de 10. Pero esto es solo un ejemplo, por lo que ni siquiera estarías intentando agregar cosas. dependiendo del código que está escribiendo y simplemente comenzaría con la implementación que le sirvió mejor.
Esperemos que alguien pueda mejorar lo que escribí aquí o usarlo para ver cómo se puede hacer esto en C#.
Me pregunto si hay algo que podría hacer con (tal vez un argumento 'params' de) [' TypedReference'] (http://stackoverflow.com/questions/4764573/why-is-typedreference-rehind-the-scenes -s-tan-rápido-y-seguro-casi mágico) – AakashM