2010-03-19 50 views
8

Một trong các cấu trúc dữ liệu trong dự án hiện tại của tôi yêu cầu tôi lưu trữ danh sách các loại khác nhau (Chuỗi, int, phao, v.v ...). Tôi cần có khả năng lưu trữ động bất kỳ số lượng danh sách nào mà không biết chúng sẽ là loại nào.Danh sách các loại khác nhau

Tôi đã cố gắng lưu trữ từng danh sách dưới dạng object, nhưng tôi gặp sự cố khi cố gắng truyền lại thành loại thích hợp (nó tiếp tục nhận ra mọi thứ dưới dạng List<String>).

Ví dụ:

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

public static void Main(string args[]) 
{ 
    // Create some lists... 

    // Populate the lists... 

    // Add the lists to myLists... 

    for (int i = 0; i < myLists.Count; i++) 
    { 
     Console.WriteLine("{0} elements in list {1}", GetNumElements(i), i); 
    } 
} 

public int GetNumElements(int index) 
{ 
    object o = myLists[index]; 

    if (o is List<int>) 
     return (o as List<int>).Count; 

    if (o is List<String>)     // <-- Always true!? 
     return (o as List<String>).Count; // <-- Returning 0 for non-String Lists 

    return -1; 
} 

Am tôi làm điều gì sai? Có cách nào tốt hơn để lưu trữ một danh sách các danh sách các loại khác nhau hoặc có cách nào tốt hơn để xác định xem có gì đó là danh sách của một loại nhất định không?

+0

Bạn có thể đăng chương trình tối thiểu nhưng hoàn chỉnh để chứng minh sự cố của bạn không? – dtb

Trả lời

10

Loại List<T> được kế thừa từ giao diện không chung chung IList. Vì tất cả các giá trị trong loại myList là intsance của List<T>, bạn có thể sử dụng chúng như là không chung chung IList. Vì vậy, bạn có thể sử dụng để đơn giản hóa rất logic của bạn

public int GetNumElements(int index) { 
    object o = myLists[index]; 
    var l = o as IList; 
    return l.Count; 
} 

Hoặc cách khác kể từ khi bạn biết rằng tất cả các giá trị được lưu trữ trong myList sẽ là một phiên bản giới hạn của List<T>, sử dụng IList như kiểu thay vì object.

List<IList> myLists = new List<IList>(); 
... 
public int GetNumElements(int index) { 
    return myList[index].Count; 
} 
+0

Tính năng này hoạt động cho đến khi tôi phải thực hiện bất kỳ thao tác nào đối với danh sách hoặc khi tôi phải truy xuất phần tử từ danh sách sau khi được chèn vào danh sách chính. Có cách nào dễ dàng để biết Loại 'IList' là gì không? – themarshal

+0

@themarshal không thực sự. Cách duy nhất để thực sự kiểm tra là sử dụng toán tử 'as' để truyền đến các kiểu được hỗ trợ và thao tác chúng – JaredPar

+0

Cuối cùng tôi đã tìm ra cách để theo dõi loại danh sách khi nó được chèn vào.Lý do mọi thứ liên tục được đọc dưới dạng danh sách Chuỗi là vì khi tôi tạo danh sách dựa trên loại, loại "Số nguyên" đã tạo nhầm Danh sách . Rất tiếc! – themarshal

2

Tôi nhận thấy đây là một lỗi thời, nhưng .NET 4 đã cho chúng tôi một cách khác. Điều gì xảy ra nếu bạn muốn một Danh sách trong đó X là một Danh sách khác, và y là loại nào?

Nói cách khác, một Danh sách> bạn có thể thử đối tượng, nhưng sau đó bạn sẽ không bao giờ cố gắng truyền lại thứ gì đó về kiểu gốc, như trên.

Vì vậy, đây là một tình huống hiếm khi có thể sử dụng loại dữ liệu động mới. Tất nhiên, nó cho phép bạn phá vỡ an toàn loại, nhưng trong trường hợp này, vì chúng ta sẽ luôn xử lý danh sách một số loại, thật công bằng khi nói rằng nó sẽ có thuộc tính ".Count".

Vì vậy, một cái gì đó như:

var myMainList = new List<List<dynamic>>(); 
var myInnerList1 = new List<string> { "A", "B", "C" }; 
var myInnerList2 = new List<int> { 1, 2, 3, 4, 5 }; 
myMainList.Add(myInnerList1); 
myMainList.Add(myInnerList2); 

// when we come to try and read the number of values in the list.. 
Console.WriteLine("inner list 1 : {0}", myMainList[0].Count); 
Console.WriteLine("inner list 2 : {0}", myMainList[1].Count); 

Vì vậy, sử dụng năng động cho phép chúng tôi để thả các kiểm tra an toàn kiểu. Nhiều nhà phát triển chống lại việc sử dụng năng động. Tôi thực sự quyết định tích cực tìm kiếm một cái gì đó liên quan đến một danh sách các danh sách các loại khác nhau, và đến đây. Vì vậy, tôi đã thêm giải pháp của riêng mình vào vấn đề của riêng mình. nó thực sự được sử dụng như một danh sách dữ liệu thử nghiệm, trong đó một danh sách bên ngoài là một danh sách các tên tham số và một danh sách bộ sưu tập 9inner) của các giá trị để sử dụng trong thử nghiệm. Đây là các thông số khác nhau cho mỗi thông số và tôi không muốn liên tục truyền lại từ đối tượng sang các loại mà tôi biết trong quá trình tạo mã nguồn. Tôi thấy đây là một giải pháp tiện lợi.

+0

mã của bạn thậm chí không biên dịch! – Arvand

Các vấn đề liên quan