proszę sprawdzić następujące segmenty kodów:metoda Generic obsługuje IEnumerable inaczej niż typu rodzajowego
public interface ICountable { }
public class Counter<T>
where T : ICountable
{
public int Count(IEnumerable<T> items)
{
return 0;
}
public int Count(T Item)
{
return 0;
}
}
public class Counter
{
public int Count<T>(IEnumerable<T> items)
where T : ICountable
{
return 0;
}
public int Count<T>(T Item)
where T : ICountable
{
return 0;
}
}
Obie wersje różnią się tylko w Counter specyfikacji parametru rodzajowego. Jeden z nich definiuje jako typowy parametr, drugi jako ogólny argument. Oba ograniczają argumenty metody do implementacji interfejsu ICountable. Nazwiemy je odpowiednio specyficznymi i niespecyficznymi.
Teraz jestem zdefiniowanie klasy, która implementuje interfejsICountable oraz kolekcję przypadkach:
public class CItem : ICountable { }
var countables = new List<CItem>();
Następnie chciałbym używać obu klas licznik na zbiorach.
var specific = new Counter<CItem>();
var nonspecific = new Counter();
specific.Count(countables);
nonspecific.Count(countables);
Specyficzny licznik uznaje, że countables kolekcja powinna spaść do podpisu int Count (IEnumerable), ale niespecyficzne wersja nie robi. Wystąpił błąd:
The type '
System.Collections.Generic.List<CItem>
' cannot be used as type parameter 'T
' in the generic type or method 'Counter.Count<T>(T)
'. There is no implicit reference conversion fromList<CItem>
' toICountable
.
Wygląda na to, że wersja nieokreślona używa niewłaściwego podpisu do kolekcji.
Dlaczego zachowują się inaczej? W jaki sposób można określić nieokreśloną wersję, aby zachowywać się tak samo jak inne?
Uwaga: Wiem, że ten przykład nie jest realistyczny. Jednak napotkałem ten problem w dość skomplikowanym scenariuszu z metodami rozszerzenia. Używam tych klas dla uproszczenia
góry dzięki
jeśli typ rodzajowy wyraźnie na jak 'nonspecific.Count (countables)', które będą pracować zbyt –
jeśli zdefiniować '' countables' z IEnumerable countables = new List (); 'poprawna przeciążenie jest wybierany . –
SWeko
Dwa przeciążenia metody Count() są niejednoznaczne, oba mogą przyjąć List jako argument. Jednak jeden z nich narusza ograniczenie w * specyficznym * przypadku przekazania listy. To nie wystarczy, jeśli użyjesz innego typu, który implementuje zarówno IEnumerable * i * ICountable, to jest naprawdę niejednoznaczny. C# nie pozwala zadeklarować typowego typu/metody, które mogą losowo nie skompilować. –