C# cast Dictionary to Dictionary (Involving Reflection)

前端 未结 8 981
无人及你
无人及你 2021-01-04 10:04

Is it possible to cast a Dictionary to a consistent intermediate generic type? So I would be able to cast <

8条回答
  •  醉梦人生
    2021-01-04 10:20

    When I stumbled onto the same situation, I created the following helper:

    /// 
    /// Casts a dictionary object to the desired Dictionary type.
    /// 
    /// The target Key type.
    /// The target value type.
    /// The dictionary to cast.
    /// A copy of the input dictionary, casted to the provided types.
    private Dictionary CastDictionary(IDictionary dictionary)
    {
        // Get the dictionary's type.
        var dictionaryType = typeof(Dictionary);
    
        // If the input is not a dictionary.
        if (dictionaryType.IsAssignableFrom(typeof(Dictionary<,>)))
        {
            // Throw an exception.
            throw new Exception("The cast to a dictionary failed: The input object is not a dictionary.");
        }
    
        // Get the generic arguments of the dictionary.
        var arguments = dictionaryType.GetGenericArguments();
    
        // If the first type of the dictionary is not a descendant of TKey.
        if (!(arguments[0] is TKey || arguments[0].IsAssignableFrom(typeof(TKey)))
            // Or its second type is not a descendant of TValue.
            || !(arguments[1] is TValue || arguments[1].IsAssignableFrom(typeof(TValue))))
        {
            // Throw an exception.
            throw new Exception("The cast to a dictionary failed: The input dictionary's signature does not match <" + typeof(TKey).Name + ", " + typeof(TValue).Name + ">");
        }
    
        // Get the dictionary's default constructor.
        var constructor = dictionaryType.GetConstructor(Type.EmptyTypes);
    
        // Create a new dictionary.
        var output = (Dictionary)constructor.Invoke(null);
    
        // Loop through the dictionary's entries.
        foreach (DictionaryEntry entry in dictionary)
        {
            // Insert the entries.
            output.Add((TKey)entry.Key, (TValue)entry.Value);
        }
    
        // Return the result.
        return output;
    }
    

    Could be used in your case as follows:

    FieldInfo field = (IDictionary)this.GetType().GetField(fieldName);
    
    Dictionary dict = CastDictionary(field.GetValue(this));
    

提交回复
热议问题