2012-09-27 52 views
31

I wydają się być pewne kłopoty owinąć głowę wokół idei ogólną listę Generic list w języku C#. Myślę, że problem wynika z użycia argumentu <T>, z którym nie miałem wcześniej styczności. Czy ktoś mógłby podać krótki przykład deklarowania klasy, która jest listą, że zawiera inną listę, ale gdzie typ obiektu w nim zawartego nie jest od razu znany?Tworzenie listy list w C#

Czytałem w dokumentacji MS na Generics i nie jestem od razu pewien, czy mogę zadeklarować List<List<T>>, ani jak dokładnie przekazać parametr <T> do listy wewnętrznej.

Edycja: Dodawanie informacji

Byłoby uznającej List<List<T>> uznać tu legalne? W przypadku, gdy zastanawiasz się, buduję klasę, która pozwala mi używać ulong jako narzędzia indeksującego i (miejmy nadzieję) kroczy wokół paskudnego limitu 2GB .Net, utrzymując listę list.

public class DynamicList64<T> 
    { 
     private List<List<T>> data = new List<List<T>>(); 

     private ulong capacity = 0; 
     private const int maxnumberofitemsperlist = Int32.MaxValue; 



     public DynamicList64() 
     { 
      data = new List<List<T>>(); 
     } 

Odpowiedz

50

Szybki przykład:

List<List<string>> myList = new List<List<string>>(); 
myList.Add(new List<string> { "a", "b" }); 
myList.Add(new List<string> { "c", "d", "e" }); 
myList.Add(new List<string> { "qwerty", "asdf", "zxcv" }); 
myList.Add(new List<string> { "a", "b" }); 

// To iterate over it. 
foreach (List<string> subList in myList) 
{ 
    foreach (string item in subList) 
    { 
     Console.WriteLine(item); 
    } 
} 

Czy tego szukałeś? Lub próbujesz utworzyć nowy class, który rozszerza List<T>, który ma członka, który jest "List"?

+2

Przeczytaj jeszcze raz pytanie :) –

17

czy ten przykład, tak aby uczynić go bardziej widoczne:

public class CustomerListList : List<CustomerList> { } 

public class CustomerList : List<Customer> { } 

public class Customer 
{ 
    public int ID { get; set; } 
    public string SomethingWithText { get; set; } 
} 

i można zachować leci. do nieskończoności i dalej!

+2

+1. Dobry pomysł.Można nawet dodawać do niego określone elementy klienta, takie jak metoda 'Dodaj', przyjmująca nazwę klienta jako parametr, która automatycznie tworzy i dodaje klienta. (Potrzebujesz do tego ograniczenia 'where T: new()'). –

+1

Możesz użyć zamiast tego aliasu ', ponieważ treść klas jest pusta – Servy

+0

@Servy, jedna w górę, zmieniłem post, aby było to jak najbardziej jasne dla każdego, kto to zobaczy, tks – RollRoll

2
public class ListOfLists<T> : List<List<T>> 
{ 
} 


var myList = new ListOfLists<string>(); 
1

Też bawiłem się z tym pomysłem, ale próbowałem osiągnąć nieco inne zachowanie. Mój pomysł polegał na stworzeniu listy, która dziedziczy się, tworząc strukturę danych, która z natury pozwala na osadzanie list na listach w listach na listach ... w nieskończoność!

Wykonanie

//InfiniteList<T> is a list of itself... 
public class InfiniteList<T> : List<InfiniteList<T>> 
{ 
    //This is necessary to allow your lists to store values (of type T). 
    public T Value { set; get; } 
} 

T ogólny parametr typu. Ma zapewnić bezpieczeństwo w klasie. Tworząc instancję InfiniteList, zastępujesz T typem, w którym chcesz zapełnić listę, lub w tym przypadku typem właściwości Value.

Przykład

//The InfiniteList.Value property will be of type string 
InfiniteList<string> list = new InfiniteList<string>(); 

A "działa" przykład tego, gdzie T jest samo w sobie listę typu string!

//Create an instance of InfiniteList where T is List<string> 
InfiniteList<List<string>> list = new InfiniteList<List<string>>(); 

//Add a new instance of InfiniteList<List<string>> to "list" instance. 
list.Add(new InfiniteList<List<string>>()); 

//access the first element of "list". Access the Value property, and add a new string to it. 
list[0].Value.Add("Hello World"); 
0

Nie należy używać listy zagnieżdżonej na liście.

List<List<T>> 

nie jest legalne, nawet jeśli T był zdefiniowany.

https://msdn.microsoft.com/en-us/library/ms182144.aspx

+1

Co masz na myśli, że nie jest legalne? Oczywiście, że jest. To, z czym się łączysz, jest tylko ostrzeżeniem o projekcie. Takiej składni jest korzystnie unikać, szczególnie w publicznych API, ale istnieją ważne przypadki użycia do takich rzeczy. –