2012-04-18 37 views
6

Có thể đúc Dictionary<string, Anything> cho một loại generic trung gian nhất quán không? Vì vậy, tôi có thể đúc <string, string>, <string, bool>, <string, int>, <string, anything> tất cả vào cùng một loại từ điển?C# truyền từ điển <string, AnyType> vào từ điển <string, Object> (tham chiếu Reflection)

tôi đang làm việc trên một dự án mà đang sử dụng phản ánh nặng và tôi cần để có thể xử lý các loại từ điển như vậy:

FieldInfo field = this.GetType().GetField(fieldName); 
Dictionary<string, Object> dict = (Dictionary<string, Object>)field.GetValue(this); 

Đoạn mã trên là những gì tôi đang có và chương trình luôn luôn thất bại tại cast từ field.GetValue đến chung Dictionary<string, Object>.

Có cách nào để thực hiện việc này không? Hay tôi nên tìm ra một cách khác để xử lý những Từ điển này?

Mọi trợ giúp sẽ được đánh giá cao.

Trả lời

8

Sau AakashM's answer, Cast dường như không chơi bóng. Bạn có thể sử dụng phương thức trợ giúp nhỏ bằng cách sử dụng một phương thức trợ giúp nhỏ:

IDictionary dictionary = (IDictionary)field.GetValue(this); 
Dictionary<string, object> newDictionary = CastDict(dictionary) 
              .ToDictionary(entry => (string)entry.Key, 
                 entry => entry.Value); 

private IEnumerable<DictionaryEntry> CastDict(IDictionary dictionary) 
{ 
    foreach (DictionaryEntry entry in dictionary) 
    { 
     yield return entry; 
    } 
} 

Việc nhập vịt trong foreach rất thuận tiện trong trường hợp này.

+0

Điều này làm việc như một say mê, Cảm ơn bạn cả AakashM và Gibsnag. Điều này đã gây rắc rối cho tôi một thời gian. –

+2

Không cần thiết cho phương thức CastDict đặc biệt, bạn chỉ có thể sử dụng toán tử Cast () LINQ bình thường. –

5

Điều này có giúp ích cho bạn không?

Dictionary<a, b> output = 
    input.ToDictionary(item => item.Key, item => (SomeType)item.Value); 
+0

Tôi thực sự không thể gọi phương thức ToDictionary vì tôi đang sử dụng sự phản chiếu. Tôi có thể sử dụng nhiều phản xạ hơn để có được phương pháp ToDictionary, nhưng sau đó tôi sẽ không chắc chắn về cách vượt qua các loại tham số đó vào nó. –

8

Thậm chí nếu bạn có thể tìm thấy một số cách để thể hiện này, nó sẽ là điều sai trái để làm - đó là không đúng sự thật rằng một Dictionary<string, bool> một Dictionary<string, object>, vì vậy chúng tôi chắc chắn không muốn để đúc . Hãy xem xét rằng nếu chúng tôi có thể truyền, chúng tôi có thể thử và đặt một giá trị là string, rõ ràng là không phù hợp!

Những gì chúng ta có thể làm được, tuy nhiên, được đúc vào phi generic IDictionary (mà tất cả Dictionary<,> s thực hiện), sau đó sử dụng để xây dựng một mớiDictionary<string, object> với các giá trị như nhau:

FieldInfo field = this.GetType().GetField(fieldName); 
IDictionary dictionary = (IDictionary)field.GetValue(this); 
Dictionary<string, object> newDictionary = 
    dictionary 
    .Cast<dynamic>() 
    .ToDictionary(entry => (string)entry.Key, 
        entry => entry.Value); 

(lưu ý rằng bạn không thể sử dụng .Cast<DictionaryEntry> vào đây để the reasons discussed here. Nếu bạn pre-C# 4, và do đó, không có dynamic, bạn sẽ phải làm việc đếm bằng tay, như Gibsnag's answer does)

+0

Tôi vẫn gặp lỗi "Truyền được chỉ định không hợp lệ" với mã đó. Ý tưởng nào? –

+0

Loại thực tế của đối tượng 'field.GetValue()' trả về là gì? – AakashM

+0

Tôi cũng biết một thực tế là nó đang cố gắng để có được một 'Từ điển ' nhưng đó chỉ là vì nó là trường hợp thử nghiệm đầu tiên của tôi. Trong suốt thời gian chạy 'Console.WriteLine (field.GetValue (this) .GetType(). Name);' in ra "Dictionary'2". Chỉnh sửa: Tôi chỉ chạy 'Console.WriteLine (field.GetValue (this));' và có 'System.Collections.Generic.Dictionary'2 [System.String, System.String]' –

0

Có Có thể cast FieldInfo-Dictionary như sau

Đây là một ví dụ, tôi đã sử dụng trong mã của tôi

Dictionary<string, string> 
       GetTheDict = FilesAndPaths.GetType() 
          .GetFields() 
          .Where(f => f.Name.Equals(pLoadFile)) 
          .Select(f => (Dictionary<string, string>)f.GetValue(FilesAndPaths)) 
          .Single(); 
0

Xem xét liệu đúc đến và đi từ object thực sự là cần thiết. Tôi bắt đầu xuống con đường đó và vấp phải bài viết này, trước khi nhận ra tôi có thể đạt được những gì tôi cần thông qua Generics hơn là chuyển đổi. Ví dụ;

class DictionaryUtils<T> 
{ 
    public static T ValueOrDefault(IDictionary<string, T> dictionary, string key) 
    { 
     return dictionary.ContainsKey(key) ? dictionary[key] : default(T); 
    } 
} 

Mã bit này sạch hơn và nhanh hơn mã chuyển đổi tương đương được hiển thị trong các câu trả lời khác.

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