Moje pytanie dotyczy sprawdzania typu w łańcuchu metod ogólnych. Załóżmy, że mam metodę rozszerzenia, która próbuje przekonwertować tablicę bajtów na int, decimal, string lub DateTime.Unikaj nadmiernego sprawdzania typów w metodach ogólnych?
public static T Read<T>(this ByteContainer ba, int size, string format) where T : struct, IConvertible
{
var s = string.Concat(ba.Bytes.Select(b => b.ToString(format)).ToArray());
var magic = FromString<T>(s);
return (T)Convert.ChangeType(magic, typeof(T));
}
Wywołuje metodę o nazwie FromString, która tłumaczy połączony ciąg na określony typ. Niestety, logika biznesowa jest całkowicie zależny od typu T. więc skończyć z megalitycznych if-else bloku:
private static T FromString<T>(string s) where T : struct
{
if (typeof(T).Equals(typeof(decimal)))
{
var x = (decimal)System.Convert.ToInt32(s)/100;
return (T)Convert.ChangeType(x, typeof(T));
}
if (typeof(T).Equals(typeof(int)))
{
var x = System.Convert.ToInt32(s);
return (T)Convert.ChangeType(x, typeof(T));
}
if (typeof(T).Equals(typeof(DateTime)))
... etc ...
}
W tym momencie, wolałbym wiele metod o tej samej nazwie i różnych rodzajów powrotów coś na wzór tego:
// <WishfulThinking>
private static decimal FromString<T>(string s)
{
return (decimal)System.Convert.ToInt32(s)/100;
}
private static int FromString<T>(string s)
{
return System.Convert.ToInt32(s);
}
// </WishfulThinking>
... ale zdaję sobie sprawę, to nie jest ważne, jak T nie może być ograniczone do określonego typu, a bez niego, wszystkie metody będą miały taką samą sprzecznych podpis.
Czy istnieje możliwy sposób wdrożenia programu FromString bez nadmiernego sprawdzania typów? A może istnieje lepszy sposób na całkowite rozwiązanie tego problemu?
To wydaje się problemu możesz rozwiązać za pomocą Wyrażeń. – lukegravitt