Stwórzmy 2 klasy. Jedna (B) będzie dziedziczyła po drugiej (A)
class A { } class B : A { }
Aby poprawić czytelność stwórzmy extension method, która będzie określała czy jeden typ dziedziczy od drugiego typu:
public static class TypeExt { public static bool IsFromType<T>(this Type type) { return typeof(T).IsAssignableFrom(type); } }
Teraz możemy sprawdzić co zwróci nam ta metoda.
Console.WriteLine(typeof(A).IsFromType<A>()); //true Console.WriteLine(typeof(B).IsFromType<A>()); //true Console.WriteLine(typeof(A).IsFromType<B>()); //false
Sprawdzamy jak będzie dla typów generycznych.
Console.WriteLine(typeof(List<B>).IsFromType<List<B>>()); //true Console.WriteLine(typeof(List<B>).IsFromType<IEnumerable<B>>()); //true
Typy generyczne są tak samo traktowane jak 'normalne' typy. Ale co będzie, kiedy argumenty w typach generycznych będą różne lub jeden argument będzie dziedziczony po drugim??
Console.WriteLine(typeof(List<B>).IsFromType<List<A>>()); //false
Nawet jeżeli typ generyczny będzie taki sam, argumenty w typie generycznym będą inne, ale w relacji dziedziczenia to nie ma zależności. Wtedy musimy porównywać argumenty tych typów generycznych.
public static bool IsGenericArgFromType<T>(this Type type) { var args1 = typeof(T).GetGenericArguments(); var args2 = type.GetGenericArguments(); return args1.Length == args2.Length && args1.Zip(args2, (arg1, arg2) => new { arg1, arg2 }) .All(x => x.arg1.IsAssignableFrom(x.arg2)); }
Console.WriteLine(typeof(List<B>).IsGenericArgFromType<List<A>>()); //true Console.WriteLine(typeof(List<string>).IsGenericArgFromType<List<object>>()); //truePomimo tego, że argumenty w typie generycznym są w relacji dziedziczenia (przyporządkowania) to te dwa type nie są przyporządkowane do siebie. Taki sam problem jest, gdy mamy listę stringów i listę obiektów. W naturalny sposób lista stringów powinna być przyporządkowana do listy obiektów, ale tak nie jest.
Brak komentarzy:
Prześlij komentarz