dynamic testing, casting and instantiating generic types

I'm trying to understand how to manipulate generic types at runtime but can't seem to get at what I'm looking for. For example:

object obj = new Dictionary<string, object>();

So I now have generic dictionary object. How do I test obj to determine it is indeed a generic dictionary Is there something similar to:

if (obj is Dictionary<what goes here >)  

Then once I know this object is a generic dictionary, how do I create a typed reference to it

Dictionary<what goes here > typedReference = (Dictionary<What goes here >)obj;

I want to be then be able to add items to the dictionary

typedReference.Add((what goes here)key, (what goes here)value).


Does C# have a way to state any of these things or must reflection be used

Thanks,
Ray



Answer this question

dynamic testing, casting and instantiating generic types

  • Tim Farley

    To sum up, if I want to manipulate a generic dictionary as such, I MUST know the types involved while writing the code (no late binding to generic dictionaries -- no implicit or explicit conversion).

    To actually determine (obj is Dictionary<TKey, TValue>) I must use reflection to walk obj's inheritance heirachy. Once obj is determined to be a generic dictionary, it can only be manipulated using interfaces or reflection.

    - Ray

  • engelbmj

    or wrap the Dictionary<T,U> in your own class MyDictionary<T,U> to keep track of T and U, perhaps, using T.GetType()

    If you can elaborate on why you need to forget the types involved i've not been in such a situation, so i wonder how this could arise.



  • Polarina


    Yes,  if (obj is Dictionary<string, object>) will work if the dictionary is declared as Dictionary<string, object>. But the following will fail:

    class Foo : object {} ;

    object obj = new Dictionary<string, Foo>();

    Debug.Assert(obj is Dictionary<string, object>);

    Intuitively, I would think this should work since Foo is indeed derived from object and Foo is an object. I further expect Debug.Assert(obj is Dictionary<object, object>) to succeed.

    - Ray

  • Shobha Santosh

    Ray,

    you can do the following:

    object obj = new Dictionary<string, object>();

    if (obj is Dictionary<string, object>)

    {

    Console.Write("Object is a dictionary");

    }

    Dictionary<string, object> typedRef = obj as Dictionary<string, object>;

    // check that obj is not null...

    typedRef.Add("myKey", DateTime.Now);

    Regards,
    Andres.


  • BarJ

    There are probably as many ways for this to arise as there are combinations of keys and values. I won't go into the specifics of my scenario since that wasn't the original intent of my post. The original intent was to understand the limitations of generics and how to best make use of them. I had thought I was missing something at first but now better understand just how limited generics really are.

    Generics and generic code are really not all that compatible. For example I might want to write some routine to process a generic dictionary:

    void Process(Dictionary<object, object> dictionary)
    {
        // process key/value pairs
    }

    The problem is that there is no way to specify the dictionary parameter to work with all generic dictionaries. In this case, I could fall back to IDictionary and accomplish the Process(IDictionary dictionary) routine but that's exactly the point If Dictionary<> didn't implement IDictionary the Process() routine would require jumping through reflection hoops to get at the dictionary's data or execute methods on it. Hoops often attract bugs.

    My take on this is that if you want the type safety of generics, it should be backed by a non type safe ancestor/interface so that abstract/generic code can be written against the generic type and the generic type also becomes  implicitly/explicitly convertible.

    This defeats the type safety of generics but if implicit/explicit conversion were available on generic types, the type safety could be dragged along in the conversion.


    - Ray














  • KSC1

    The reason why intuition fails in this case is because there is no implicit or explicit conversion from Dictionary<string,object> to Dictionary<string,Foo>, and hence the 'is' operator fails.

  • dynamic testing, casting and instantiating generic types