Сбой компиляции, если определения делегатов помещены в другой проект? - PullRequest
6 голосов
/ 18 июля 2010

ОБНОВЛЕНИЕ: Я подал это как проблему в Microsoft Connect , если вы можете воспроизвести это и / или хотели бы увидеть это исправлено, пожалуйста, помогите проголосовать за проблему там.


Я пытаюсь решить эту проблему в течение нескольких часов.
Буду очень признателен за любую идею / совет, что вы можете придумать.

Прежде всего, у меня есть3 файла Class.cs Definitions.cs и Program.cs.Я вставил содержимое файла на http://pastie.org/1049492, чтобы вы могли его попробовать.

Проблема в том, что, если у вас есть ВСЕ 3 файла в одном проекте консольного приложения.Приложение компилируется и работает просто отлично.

Если, тем не менее, у меня есть Class.cs и Definitions.cs в проекте "библиотека", на который ссылается проект основного приложения консоли, в котором есть только Program.cs файл, компиляция завершается неудачно:

  • Делегат Act не принимает 2 аргумента.
  • Невозможно преобразовать лямбда-выражение в тип делегата 'DC.Lib.Produce', так как некоторые изтипы возврата в блоке неявно преобразуются в тип возврата делегата ...

Вот полное решение с 3 проектами - 1 со всеми файлами, объединенными вместе, а другой с определениями, вставленными вдругой проект:
http://dl.dropbox.com/u/149124/DummyConsole.zip

Я использую VS2010 RTW Professional Edition.

Ответы [ 2 ]

8 голосов
/ 18 июля 2010

Интересно.Я думаю вы обнаружили реальную ошибку в компиляторе C # - хотя я могу упустить что-то неуловимое.Я написал несколько упрощенную версию, в которой исключены возможности перегрузки и т. Д. И которая обходится без дополнительного метода:

// 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.");
    }    
}

Демонстрация компиляции как одной сборки без ошибок:

> csc Test.cs Definitions.cs

Демонстрация компиляции в виде двух сборок с ошибками:

> 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

Я не могу придумать любую причину, по которой это должно отличаться в разных сборках, поскольку все общедоступно.Спецификация редко говорит о границах сборки, кроме как по internal причинам.

Интересно, что я получаю одинаковую ошибку как для компиляторов C # 3, так и для 4.

Отправляя электронное письмо Эрику и Мэдсу сейчас ...

РЕДАКТИРОВАТЬ: Обратите внимание, что вы можете обойти это, используя явный список параметров.Например, в моем примере кода это будет работать:

Produce<string> produce =
    (Bar<string> next) => input => next(input, "This string should appear.");
1 голос
/ 30 марта 2011

Я решил это, переименовав C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Microsoft.CSharp.targets (не удаляйте его!), Что является предупреждением в окне вывода.Новый проект работает нормально, но предыдущий не может быть загружен.После этого я снова переименовал файл в его оригинальное имя.Теперь оба проекта могут быть скомпилированы без ошибок.Это эмпирическое решение, но я надеюсь, что оно поможет

...