Jednym z powodów może być:
class Foo<out T>
{
T _store;
public T Get()
{
_store = default(T);
return _store;
}
}
Ta klasa zawiera funkcję, która nie jest kowariantna, ponieważ ma pole i pola mogą być ustawione na wartości. Jest on jednak wykorzystywany w sposób kowariancyjny, ponieważ przypisuje mu się tylko wartość domyślną i tylko w przypadku każdego przypadku, w którym faktycznie używana jest kowariancja, będzie ona dostępna tylko w jednym przypadku.
Jako takie nie jest jasne, czy możemy na to pozwolić. Niewykonanie tego mogłoby zirytować użytkowników (w końcu pasuje do tych samych potencjalnych zasad, które sugerujesz), ale pozwolenie na to jest trudne (analiza jest już trochę trudna i nie jesteśmy nawet w stanie zacząć polować na naprawdę podchwytliwe przypadki).
Z drugiej strony, analiza ta jest znacznie prostsza:
void Main()
{
IFoo<object> foo = new Foo<string>();
Console.WriteLine(foo.Get());
}
interface IFoo<out T>
{
T Get();
}
class Foo<T> : IFoo<T>
{
T _store;
public T Get()
{
_store = default(T);
return _store;
}
}
Jest to łatwe do ustalenia, że żaden z realizacji IFoo<T>
przerw kowariancja, ponieważ nie ma żadnych. Wszystko, co konieczne, to upewnienie się, że nie ma potrzeby używania parametru T
jako parametru (w tym parametru metody ustawiającej) i gotowe.
Fakt, że potencjalne ograniczenie jest o wiele bardziej uciążliwe dla klasy niż z interfejsu z podobnych powodów, również zmniejsza stopień użyteczności klas kowariancji. Z pewnością nie byłyby one bezużyteczne, ale równowaga tego, jak użyteczne byłyby one nad tym, ile pracy będzie polegało na określeniu i wdrożeniu zasad dotyczących tego, co mogliby zrobić, jest znacznie mniejsza niż równowaga między tym, jak użyteczne są kowariantne interfejsy nad tym, jak dużo pracy trzeba było określić i wdrożyć.
Z pewnością różnica jest wystarczająca, że minęło punkt "dobrze, jeśli masz zamiar pozwolić X, byłoby głupie, aby nie pozwolić Y ...".
Wynika to z ograniczenia CLR. Teraz byłoby fajnie, gdybyś zmodyfikował swoje pytanie, aby ktoś mógł odpowiedzieć na pytanie, dlaczego istnieje ograniczenie CLR. – Stilgar
@Stilgar: Nie mógłbyś odpowiedzieć "Nie jest to obsługiwane z powodu tej rzeczy w podstawowej implementacji CLR"? – Chris
Klasy muszą martwić się szczegółami implementacji - delegaci i interfejsy tego nie robią.Wykonanie tej pracy wymagałoby wiele pracy. Pytanie, dlaczego nikt z zespołu C# nie wykonał tej pracy, wydaje się nieco bezsensowne - nie, nie jest wspierane, koniec historii. –