Cannot implicitly convert type System.Collections.Generic.Dictionary<System.Tuple<int,int,string>, AnonymousType#1>

Programming Newbie picture Programming Newbie · Aug 14, 2012 · Viewed 9.4k times · Source

I have the following dictionary in a method:

var nmDict = xelem.Descendants(plantNS + "Month").ToDictionary(
    k => new Tuple<int, int, string>(int.Parse(k.Ancestors(plantNS + "Year").First().Attribute("Year").Value), Int32.Parse(k.Attribute("Month1").Value), k.Ancestors(plantNS + "Report").First().Attribute("Location").Value.ToString()),
    v => { 
             var detail = v.Descendants(plantNS + "Details").First();                
             return
                 new
                    {
                      BaseHours = detail.Attribute("BaseHours").Value,
                      OvertimeHours = detail.Attribute("OvertimeHours").Value
                    };
         });

I need to return nmDict. The problem is that I cannot figure out how to label my method signature. I have tried the following:

protected IDictionary<XElement, XElement> OvertimereportData(HarvestTargetTimeRangeUTC ranges)

The above gives me this error:

Cannot implicitly convert type System.Collections.Generic.Dictionary<System.Tuple<int,int,string>,AnonymousType#1>' to 'System.Collections.Generic.IDictionary<System.Xml.Linq.XElement,System.Xml.Linq.XElement>'. An explicit conversion exists (are you missing a cast?) 


protected IDictionary<Tuple, XElement> OvertimereportData(HarvestTargetTimeRangeUTC ranges)

gives me this error:

'System.Tuple': static types cannot be used as type arguments   

I do not know what to do.

Answer

lc. picture lc. · Aug 14, 2012

The short answer: You can't return anonymous types from a function.

The long answer: Your dictionary's value type is anonymous {BaseHours, OvertimeHours} which cannot be returned from a function or passed as an argument (except as an object, but that does nobody any good unless you go through the hassle of reflecting into it). Either define a class/struct with BaseHours and OvertimeHours in it, or use a tuple. The former is probably slightly better because you can keep the names BaseHours and OvertimeHours; with a tuple you just get Value1 and Value2.