Jaka jest wspólna reguła, aby sprawdzić, czy IEnumerable<T1>
kowariant do ?Jak sprawdzić, czy `IEnumerable <T1>` covariant do `IEnumerable <T2>`?
Zrobiłem kilka eksperymentów:
1.
Object Obj = "Test string";
IEnumerable<Object> Objs = new String[100];
działa, ponieważ IEnumerable<out T>
jest kowariantna i String
dziedziczy Object
.
2.
interface MyInterface{}
struct MyStruct:MyInterface{}
.....
Object V = new MyStruct();
Console.WriteLine(new MyStruct() is Object); // Output: True.
IEnumerable<Object> Vs = new MyStruct[100]; // Compilation error here
MyStruct
jest rzeczywiście Object
, ale to nie działa, ponieważ Object
jest typ referencyjny i MyStruct
jest typ wartości. OK, widzę tutaj pewną logikę.
3.
Console.WriteLine(new MyStruct() is ValueType); // Output: "True"
ValueType V2 = new MyStruct();
IEnumerable<ValueType> Vs2 = new MyStruct[100]; // Compilation error here
Powinna działać, ponieważ IEnumerable<out T>
jest kowariantna i MyStruct
JEST ValueType
, ale nie działa ... OK, może MyStruct
rzeczywistości nie inheritst ValueType
....
4.
MyInterface V3 = new MyStruct();
Console.WriteLine(V3 is MyInterface); // Output: "True"
IEnumerable<MyInterface> Vs3 = new MyStruct[100]; // Compilation error here
Nawet w ten sposób: "Nie można przekonwertować MyStruct na MyInterface". Naprawdę?? Po prostu to zrobił jeden wiersz przed ...
Próbowałem sformułować wspólną zasadę:
public static bool IsCovariantIEnumerable(Type T1, Type T2 ){
return (T2.IsAssignableFrom(T1)) && !T2.IsValueType; // Is this correct??
}
Więc pytanie brzmi, jak ustalić, czy rzeczywiście IEnumerable<T1>
kowariantna do IEnumerable<T2>
? Czy moja funkcja IsCovariantIEnumerable(...)
jest poprawna? Jeśli tak, czy istnieje jakiś prostszy sposób na sprawdzenie? Jeśli nie, jak to naprawić?
Zobacz także te artykuły: 1, 2.
Typy wartości po prostu nie obsługują współzmienności; nie powinno to dziwić, ponieważ typy wartości nie wspierają wcale * dziedziczenia *. Jeśli potrzebujesz użyć typu wartości jako interfejsu i/lub 'obiektu', musisz go zaznaczyć - np. 'array.Cast'. Nie jest jasne, jakiej części tego nie rozumiesz, biorąc pod uwagę, że pytania, które łączysz, odpowiadają również na to pytanie :) –
Luaan
@Luaan, chcę tylko mieć pełną regułę, aby sprawdzić, czy 'IEnumerable' kowariancja do 'IEnumerable '. Nadal nie jestem pewien, czy moja funkcja 'IsCovariantIEnumerable()' jest poprawna. –
Astronavigator
Pod względem obsługi interfejsów, ['IsAssignableFrom'] (https://msdn.microsoft.com/en-us/library/system.type.isassignablefrom (v = vs.110) .aspx) może działać lepiej niż' IsSubclassOf ' – grek40