locked
Type arguments for method cannot be inferred from the usage for Dictionary<,>

    Question

  • I have a function with the following signature:

    public static void WriteXmlDictionary<TKey, TValue>(XmlWriter writer, Dictionary<TKey, TValue> dict)
    {
    // do stuff
    }

    and I call it from:

           public void WriteXml(XmlWriter writer)
            {
                Type thisType = typeof(ViewInfo);
                PropertyInfo[] pi = thisType.GetProperties();
                foreach (PropertyInfo p in pi)
                {
                    if (!typeof(IDictionary).IsAssignableFrom(p.PropertyType))
                    {  

    // it's not a Dictionary, do stuff
                    }
                    else
                    {
                        IDictionary dict = (IDictionary)p.GetValue(this, null);
                        if (dict != null)
                        {
                            WriteXmlDictionary(writer, dict);
                        }
                    }
                }
            }

     

    This doesn't compile. I get the error:

     

    Error    1    The type arguments for method 'WriteXmlDictionary<TKey,TValue>(System.Xml.XmlWriter, System.Collections.Generic.Dictionary<TKey,TValue>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

    I think it is because I am trying to call a generic function whose signature specifies Dictionary<TKey, TValue> with a parameter which is of type IDictionary, and it cannot determine at compile-time what kind of IDictionary it is.

    Any ideas?

    Wednesday, August 04, 2010 9:30 PM

Answers

  • Since type inference is made at compile time, it's not possible to use information which will only be available at runtime.

    The compiler will not accept an IDictionary as a parameter to WriteXmlDictionary anyway.

    You need to use reflection to call WriteXmlDictionary.

    Something like:

    typeof(Program).GetMethod("WriteXmlDictionary")
     .MakeGenericMethod(dict.GetType().GetGenericArguments()).Invoke(null, new object[] { writer, dict });
    
    • Marked as answer by blimeycoder Thursday, August 05, 2010 2:21 PM
    Thursday, August 05, 2010 10:21 AM

All replies

  • You will have to get the dictionary type parameters and make the generic method call using reflection, specifying the TKey and TValue parameters
    Zaiden http://zPod.com.ar
    Wednesday, August 04, 2010 10:39 PM
  • Usually you don't need to specify the generic parameters in a method call, but if the compiler needs help, just provide them:

    WriteXmlDictionary<XmlWriter, IDictionary>(writer, dict); 
    
    You certainly don't need to use reflection - that's drastic overkill.
    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Wednesday, August 04, 2010 10:52 PM
  • An IDictionary cannot be cast implicitly to Dictionary<TKey, TValue>.
    Thursday, August 05, 2010 7:15 AM
  • Hi,

    This has indeed got to do with the types. You're casting the property value to an IDictionary. That however will disable the compiler to infer the types involved. I'm actually not sure whether it is at all possible to have the compiler infer the types for TKey and TValue when you use reflection. I've tried to dabble with your example a little, but to no avail. I tired to cast to IDictionary<,> so it would only go through on generic implementations. But the problem is actually in the line where you cast the value of the property to IDictionary.

    I am not aware of a quick way to achieve what you aim for. I found the following article though: http://stackoverflow.com/questions/1003023/cast-to-generic-type-in-c. It is a bit like the problem you are facing in your code. But once again, having the compiler infer the type for TKey and TValue is probably not possible it you work with reflection.

    Hope this helps
    Meile Zetstra


    http://blogger.xs4all.nl/mzetstra

    Thursday, August 05, 2010 7:28 AM
  • Since type inference is made at compile time, it's not possible to use information which will only be available at runtime.

    The compiler will not accept an IDictionary as a parameter to WriteXmlDictionary anyway.

    You need to use reflection to call WriteXmlDictionary.

    Something like:

    typeof(Program).GetMethod("WriteXmlDictionary")
     .MakeGenericMethod(dict.GetType().GetGenericArguments()).Invoke(null, new object[] { writer, dict });
    
    • Marked as answer by blimeycoder Thursday, August 05, 2010 2:21 PM
    Thursday, August 05, 2010 10:21 AM