Search code examples
c#compact-frameworkwindows-ceextension-methodsgeneric-type-argument

Why can the type arguments not be inferred, and how can I specify them explicitly?


This code, adapted from an answer here works in a .NET 4.5.1 app in Visual Studio 2013:

private void button42_Click(object sender, EventArgs e)
{
    List<SiteQuery> sitequeries = GetListOfSiteQueries();
    foreach (SiteQuery sitequery in sitequeries)
    {
        // TODO: Insert into table
    }
}

private List<SiteQuery> GetListOfSiteQueries()
{
    ArrayList arrList = 
FetchSiteQuery("http://localhost:21608/api/sitequery/getall/dbill/ppus/42");
    String omnivore = "<SiteQueries>";
    foreach (String s in arrList)
    {
        omnivore += s;
    }
    omnivore += "</SiteQueries>";
    String unwantedPreamble = "<ArrayOfSiteQuery xmlns:i=\"http://www.w3.org/2001/XMLSchema-
instance\" xmlns=\"http://schemas.datacontract.org/2004/07/CStore.DomainModels.HHS\">";
    omnivore = omnivore.Replace(unwantedPreamble, String.Empty);
    omnivore = omnivore.Replace("</ArrayOfSiteQuery>", String.Empty);
    XDocument xmlDoc = XDocument.Parse(omnivore);
    List<SiteQuery> sitequeries = 
xmlDoc.Descendants("SiteQuery").Select(GetSiteQueryForXMLElement).ToList();
    return sitequeries;
}

private static SiteQuery GetSiteQueryForXMLElement(XElement sitequery)
{
    return new SiteQuery
    {
        Id = sitequery.Element("Id").Value,
        . . .

However, the same code in a .NET 3.5, Compact Framework/Windows CE app in VS 2008 fails to compile with "The type arguments for method 'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly."

It fails on this line:

List<SiteQuery> sitequeries = xmlDoc.Descendants("SiteQuery").Select(GetSiteQueryForXMLElement).ToList();

Why does identical code work in one case but not the other; is it because of the recalcitrant's code Windows CE-ness and/or because it's .NET 3.5 instead of the newer 4.5.1?

If one or both of those limitations is/are the issue, is there a workaround, or is it a "back to the coding board" situation?


Solution

  • Type inference changed in VS2010 (IIRC) - basically the compiler became slightly more capable. It's not a matter of .NET itself changing.

    Two simple options:

    • Use a lambda expression instead:

      .Select(x => GetSiteQueryForXMLElement(x))
      
    • Specify the type arguments with a method group conversion:

      .Select<XElement, SiteQuery>(GetSiteQueryForXMLElement);
      

    Either should work fine.