wiem, jest to stara sprawa, ale jeśli wszystko, co chcesz zrobić, to coś prostego jak druku te typy out, można to zrobić bardzo łatwo, bez krotki lub coś ekstra za pomocą 'dynamiczny':
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();
}
wypisze "System.Int32", "System.Double", "System.String"
Jeśli chcesz wykonać pewne działanie w tych sprawach, o ile wiem, masz dwie możliwości. Jednym z nich jest zaufanie programistom, że te typy mogą wykonywać zgodne działania, na przykład, jeśli chcesz stworzyć metodę Sumowania dowolnej liczby parametrów. Można napisać metodę jak poniżej mówiąc w jaki sposób chcesz otrzymać wynik, a jedynym warunkiem Chyba byłoby to, że operacja + działa pomiędzy tymi typami:
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();
}
z tym, wyjście na pierwszej linii będzie być "9", ponieważ dodanie do int, a druga linia będzie "10", ponieważ .5s nie zostały zaokrąglone, dodając jako podwójne. Problem z tym kodem polega na tym, że jeśli przekażesz jakiś niekompatybilny typ na liście, wystąpi błąd, ponieważ typy nie mogą zostać dodane razem, a błąd nie pojawi się w czasie kompilacji, tylko w środowisku wykonawczym.
Tak więc, w zależności od przypadku użycia może być inna opcja, dlatego powiedziałem, że na początku były dwie możliwości. Zakładając, że znasz wybory możliwych typów, możesz utworzyć interfejs lub klasę abstrakcyjną i sprawić, że wszystkie te typy implementują interfejs. Na przykład poniżej. Przepraszam, to trochę szalone.I prawdopodobnie można go uprościć.
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();
}
wyjście będzie „9” tak samo jak oryginalny kod INT, z wyjątkiem jedynie wartościami rzeczywiście można przekazać jako parametry są rzeczy, które rzeczywiście zostały zdefiniowane i wiesz zadziała i nie powoduje żadnych błędów. Oczywiście, musiałbyś stworzyć nowe klasy, takie jak DoubleableInt, DoubleableString, etc., aby ponownie utworzyć drugi wynik 10. Ale to tylko przykład, więc nawet nie próbowałbyś dodawać rzeczy w ogóle w zależności od tego, jaki kod piszesz, a dopiero zaczynasz od implementacji, która służyła Ci najlepiej.
Mam nadzieję, że ktoś może poprawić to, co tu napisałem, lub użyć go, aby zobaczyć, jak można to zrobić w języku C#.
Zastanawiam się, czy jest coś, co można zrobić (być może argument "params") ["TypedReference"] (http://stackoverflow.com/questions/4764573/why-is-typedreference-behind-the-scenes -to-tak-szybko-i-safe-prawie-magiczne) – AakashM