Compilation fails if delegate definitions is put i

2020-02-24 04:14发布

问题:

UPDATE: I've filed this as an issue on Microsoft Connect if you can reproduce this and/or would love to see this fixed please help vote up the issue over there.


I've been trying to solve this problem for hours now.
Would really appreciate whatever idea/advice you can think of.

First of all, I have 3 files Class.cs Definitions.cs and Program.cs. I've pasted file contents over at http://pastie.org/1049492 for you to try out.

The problem is that, If you have ALL 3 files in the same console application project. The application compiles and runs just fine.

If however, I have Class.cs and Definitions.cs in a "library" project which is referenced to from the main console application project which has only the Program.cs file, compilation fails with:

  • Delegate Act does not take 2 arguments.
  • Cannot convert lambda expression to delegate type 'DC.Lib.Produce' because some of the return types in the block are not implicitly convertible to the delegate return type ...

Here is a complete solution with 3 projects -- 1 with all files combined together and another with the definitions put in another project:
http://dl.dropbox.com/u/149124/DummyConsole.zip

I'm using VS2010 RTW Professional edition.

回答1:

Interesting. I think you've found an actual bug in the C# compiler - although I may be missing something subtle. I've written a slightly simplified version which avoids possibilities of overloading etc coming into play, and which dispenses with the extra method:

// Definitions.cs
public interface IData { }
public delegate IData Foo(IData input);
public delegate IData Bar<T>(IData input, T extraInfo);
public delegate Foo Produce<T>(Bar<T> next);

// Test.cs
class Test
{
    static void Main()
    {
        Produce<string> produce = 
            next => input => next(input, "This string should appear.");
    }    
}

Demonstration of compiling as one assembly, with no errors:

> csc Test.cs Definitions.cs

Demonstration of compiling as two assemblies with errors:

> csc /target:library Definitions.cs
> csc Test.cs /r:Definitions.dll

Test.cs(5,43): error CS1662: Cannot convert lambda expression 
        to delegate type 'Produce<string>'
        because some of the return types in the block are not 
        implicitly convertible to the delegate return type
Test.cs(5,52): error CS1593: Delegate 'Bar' does not take 2 arguments

I can't think of any reason why this should be different across different assemblies, as everything's public. The spec rarely talks about assembly boundaries other than for internal reasons.

Interestingly, I get the same error for both the C# 3 and 4 compilers.

Emailing Eric and Mads now...

EDIT: Note that you can work around this using an explicit parameter list. For example, in my sample code, this will work:

Produce<string> produce =
    (Bar<string> next) => input => next(input, "This string should appear.");


回答2:

I resolved this by renaming of C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.targets (don't delete it!) which is a warning in output window. The new project wroks fine now but the previous one couldn't be loaded. After that I renamed the file again to it's original name. Now both projects can be compiled without errors. This is an empiric solution but I hope it helps