3
votes
namespace TestLibrary
{
    [TestFixture]
    public class Class1
    {
        public delegate T Initializer<T>();

        public static T MyGenericMethod<T>(Initializer<T> initializer) where T : class
        {
            return initializer != null ? initializer() : null;
        }

        [Test]
        public void Test()
        {
            var result = MyGenericMethod(MyInitializer);
            Assert.IsNotNull(result);
        }

        private object MyInitializer()
        {
            return new object();
        }
    }
}

This is a functioning piece of code when running in Visual Studion 2010. If I try to build this using MSBUILD from command line...

"c:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe" Solution1.sln

... I get very familiar error message:

The type arguments for method 'Method name' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Any ideas?

1
Have you tried using C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ? Could perhaps be a different C# compiler version between VS2010 and 3.5 MSBuild?Adam Houldsworth
Are you referencing the NUnit dll on the command line using /r:NUnit.dll or something like that. Hope this helps.Jeremy E
This version of msbuild actually works for this. But I am kind of stuck with Framework 3.5, because of our production environment. Am I able to target 3.5 Framework while using this version of msbuild? Using /tv:3.5 option will get me an error again.Radek Stromský
@Radex I changed my comment to an answer.Adam Houldsworth

1 Answers

6
votes

This appears to be a difference between the compiler versions used by VS 2010 and MSBuild 3.5. This makes sense as type inference was improved a lot in later compiler versions.

If you need to use MSBuild 3.5, you'll need to correct your code:

var result = MyGenericMethod<object>(MyInitializer);

However, you should be able to use MSBuild v4 and target the 3.5 framework. You can also target this framework in VS 2010. Based on the fact that when targeting 3.5 using VS 2010 the code compiles, I think it will likely work via MSBuild v4.

Courtesy of Radex in the comments:

c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" Solution1.sln /p:TargetFrameworkVersion=v3.5

Just to clarify, this is my educated-guess answer based on the comments.

Not sure if this is relevant, but I found this on MSDN: http://msdn.microsoft.com/en-us/library/ee855831.aspx

Method group type inference

The compiler can infer both generic and non-generic delegates for method groups, which might introduce ambiguity.

In C# 2008, the compiler cannot infer generic delegates for method groups. Therefore, it always uses a non-generic delegate if one exists.

In C# 2010, both generic and non-generic delegates are inferred for method groups, and the compiler is equally likely to infer either. This can introduce ambiguity if you have generic and non-generic versions of a delegate and both satisfy the requirements. For example, the following code complies in C# 2008 and calls a method that uses a non-generic delegate. In C# 2010, this code produces a compiler error that reports an ambiguous call.

Further reading:

http://togaroga.com/2009/11/smarter-type-inference-with-c-4/