Type of dictionary?

Has anyone heard of a “type dictionary” that uses types as keys and supports inheritance?

In my application, I would like to have a dictionary from types to functions, sort of like:

Dictionary<Type, Func<object, object>> Transformers;

The idea is that it will be used to transform an object in a certain way depending on its type:

// Transform an object 'obj'
object result = Transformers[obj.GetType()](obj)

A regular dictionary has the disadvantage that the type must match exactly. Therefore, if I wrote a transformer for IList <T>, you should not use it in the Transformers dictionary, because no object has type IList <T> (only T [], List <T>, etc.) In other words if obj is a List <T>, the transformer for IList <T> will not be found by searching in a regular dictionary.

Assuming there is no such thing as TypeDictionary <TValue>, I could write it if it is not too complicated. Any ideas on how to do this?

+5
source share
2 answers

You can use a dictionary with a custom comparator that uses Type.IsAssignableFrom to compare keys.

Update: As Qwertie pointed out, this will not work, because you cannot implement repeatable hash code calculation based on a type, its interfaces and ancestor classes. His answer provides a possible solution, repeating the search for hash table tables for types, interfaces, and ancestor classes until they find a match.

, , . , chain-of-responsibility. , , . , . . -, - .

+2

, , :

public class TypeDictionary<TValue> : Dictionary<Type, TValue>
{
    public new TValue this[Type key]
    {
        get {
            TValue value;
            if (TryGetValue(key, out value))
                return value;
            throw new KeyNotFoundException("Not found: " + key.Name);
        }
    }
    public new bool TryGetValue(Type key, out TValue value)
    {
        if (base.TryGetValue(key, out value))
            return true;

        Type[] interfaces = key.GetInterfaces();
        for (int i = 0; i < interfaces.Length; i++)
            if (base.TryGetValue(interfaces[i], out value))
                return true;

        Type @base = key.BaseType;
        if (@base != null && TryGetValue(@base, out value))
            return true;

        return false;
    }
}

, B A IA IB, , , : A, IA IB? , , .

, . GetInterfaces() BaseType , ( , , , ).

+1

All Articles