2011-08-26 14 views

Odpowiedz

11

Po wstawieniu int do List<object>, będzie to pudełko. Jeśli wstawisz go do List<int>, nie będzie on oznaczony ramką (dotyczy wszystkich typów wartości, zastępując int nazwą typu). Podobnie w przypadku pobierania wartości z List<object>, nastąpi rozpakowanie, ale nie dla List<int>.

List<T> jest silnie wpisany na klawiaturze, List<object> nie jest (więc tracisz czas na kompilację i możesz uderzać w środowiska uruchomieniowe).

+0

Świetna odpowiedź. Będziemy pamiętać o boksowaniu/rozpakowywaniu – Xaisoft

4

Jeśli użyjesz List<object>, nie będziesz mieć żadnego przedmiotu do pisania i będziesz musiał rzucić wszystko. Dodatkowo, jest to niebezpieczne, ponieważ możesz umieścić coś na liście i nie wiesz dokładnie, co otrzymujesz z danego przedmiotu.

+0

Dzięki za naprawienie wsporników, John. Właśnie chciałem to zrobić. –

+0

Przez "... wpisywanie pozycji ..." masz na myśli, że nie będę mógł uzyskać dostępu do właściwości lub metod, dopóki nie wykonam rzutowania. – Xaisoft

+0

To dodatkowe wsparcie dla czasu kompilacji, do którego dodajesz odpowiedni typ elementu do kolekcji. Najbardziej oczywistą wadą nie jest jednak możliwość interakcji z obiektem bez rzutowania, tak. –

9

jeśli masz List<T> masz pewność, że po utworzeniu obiektu lista zawiera tylko wystąpienia typu T, w List<object> możesz umieścić wszystko w środku.

Generics są dobrym sposobem na napisanie kodu wielokrotnego użytku o silnych typach w czasie kompilacji.

+0

Tak więc, jeśli lista może zawierać różne typy, czy lepiej jest użyć obiektu? – Xaisoft

+1

Dobra odpowiedź przy okazji. Nie myślałem o bezpieczeństwie typu z listą w przeciwieństwie do listy Xaisoft

2

Lista przyjmuje typowy typ jako argument szablonu. Tak, będzie rzeczywiście mieć listę samochodów, jeśli nie:

List<car> list = new List<car>(); 

następuje:

List<object> objlist = new List<object>(); 

Może pomieścić odniesień do niczego. Problem polega na tym, że te odniesienia są downcasted do obiektów i nie możesz używać ich członków i funkcji, dopóki nie przekształcisz ich w odpowiedni obiekt. Na przykład, jeśli odbywają się samochody w objlist, trzeba zrobić:

((car)objlist[0]).GetMaker(); 

Aby połączyć samochody GetMaker wehreas funkcji z listy można zrobić:

list[0].GetMaker(); 

Zakłada się, że co najmniej jeden samochód/obiekt na liście.

+0

Dobry przykład. Pomógł mi lepiej zrozumieć. – Xaisoft

0

Pytanie jest trochę mylące, ale myślę, że jsmarble uderzyło w jeden z głównych punktów, w którym będziesz musiał rzucić wszystko, czego potrzebujesz. Jest nieefektywny, szczególnie w przypadku typów wartości, które będą obsługiwać List<T> bez konieczności otwierania i rozpakowywania wartości.

Poświęcasz również bezpieczeństwo typu, które potencjalnie może spowodować błędy w czasie wykonywania.

1

Możesz uznać T jako ograniczenie typu na liście. Jeśli więc powiesz, że

class Vehicle {} 
class Car : Vehicle {} 
class Boat : Vehicle {} 
class SpeedBoat : Boat {} 
List<Boat> listOfBoats 

Lista może zawierać tylko typ łodzi i jej potomków, ale nie innych pojazdów. Jeśli ustawiłeś to na obiekt, lista mogłaby w zasadzie zawierać dowolny typ odniesienia.

Pamiętaj jednak, że jeśli chcesz np.wszystkie SpeedBoats z tej kolekcji możesz użyć ładnej metody rozszerzenia OfType:

//Returns IEnumerable<SpeedBoat>, casting is done for you 
var speedBoats = listOfBoats.OfType<SpeedBoat>(); 
+0

Lista pozwoli mi korzystać z samochodu i łodzi, prawda? a skoro SpeedBoat dziedziczy po Boat, który dziedziczy z Vehicle, czy mógłbym po prostu zrobić listę lub czy muszę używać rozszerzenia OfType? – Xaisoft

+0

Tak, lista (pojazdów) może zawierać samochód, łódź, łódź motorową, dowolnych potomków pojazdu. Lista NIE zezwala na np. .Dodaj (nowa łódź()). Jeśli chcesz listę z zapełnionej listy , możesz powiedzieć Lista sbs = vehicles.OfType () – edvaldig

Powiązane problemy