Подтвердить что ты не робот

Как создать совместимые с С# совместимые типы .Net 4.0 с использованием поставщиков типа F # 3.0

Я хочу генерировать "сильные" типы на основе "слабо" типизированных источников данных, используя механизм провайдера типа F # 3.0. Сгенерированные типы должны быть доступны из клиентов С# в среде, где установлен только .Net 4.0, но не .Net 4.5. Если совместимость .Net 4.0 невозможна, мы не можем использовать поставщиков типов в нашем текущем крупномасштабном проекте ERP.

До сих пор мне удалось создать MyGeneratedTypes.dll, выполнив учебник в msdn (раздел "Предоставление сгенерированных типов" ), используя ProvidedTypeDefinition из "ProvidedTypes-0.2.fs", который является частью пакета образцов F # 3.0. (Чтобы он работал, мне пришлось удалить строку "File.Delete..." из метода "ProvidedTypeDefinition.ConvertToGenerated..." ).

MyGeneratedTypes.dll имеет версию исполнения v4.0.30319, которая в порядке (время выполнения .Net 4.0). Я могу добавить ссылку на MyGeneratedTypes.dll в приложение С#/Net 4.0, а IntelliSense отображает типы и члены как ожидалось. Однако, когда я пытаюсь скомпилировать, компилятор С# выходит из строя и выдает предупреждение MSB3258: первичная ссылка "MyGeneratedTypes" не может быть решена, поскольку она имеет косвенную зависимость от сборки .NET Framework "FSharp.Core, Version = 4.3.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a", который имеет более высокую версию "4.3.0.0", чем версия "4.0.0.0" в текущей целевой структуре.

Взгляд на IL Spy подтверждает, что MyGeneratedTypes.dll действительно содержит ссылку на FSharp.Core 4.3, хотя эта ссылка совершенно не нужна. До сих пор я не нашел способа предотвратить компилятор F # от ввода этой ссылки в сгенерированную сборку. (Помимо прочего, я создал чистую сборку .Net 4.0 в С# и передал ее конструктору ProvidedTypeDefinition, но это не повлияло).

Кто-нибудь знает: а) как избавиться от ссылки, или б) если это только проблема с выпуском релиза F # 3.0, которая будет решена в финальной версии.

Edit

Разговор с @Brian привел к следующему "частичному" решению проблемы: вы можете скомпилировать "чистый С#/Net 4.0" клиент, ссылающийся на библиотеку с генерируемыми типами F # 3.0, но только путем вызова .Net 4.0 С# (csc) непосредственно из командной строки. Он не работает при компиляции в VS 2010 или в командной строке MSBuild. Я подозреваю, что это вызвано следующим поведением:

  • MyGeneratedTypes.dll генерируется в VS 2012 с механизмом поставщика типа F #.
  • Во время генерации ссылка на FSharp.Core 4.3 автоматически добавляется (даже если это не требуется) без указания в метаданных для зависимостей "SpecificVersion: true".
  • Клиент С# в VS 2010 на системной ссылке ".Net 4.5 бесплатно" MyGeneratedTypes.dll.
  • Когда клиент С# компилируется, MSBuild обнаруживает косвенную ссылку на FSharp.Core 4.3 внутри MyGeneratedTypes.dll.
  • Поскольку косвенная ссылка существует с "SpecificVersion: false", MSBuild выдает предупреждение MSB3257 и отказывается передать прямую ссылку /r: "MyGeneratedTypes.dll" компилятору С# (csc). (Примечание: предупреждения MSBuild не могут быть подавлены каким-либо образом.)
  • Компилятор С# (csc) вызывается MSBuild без /r: "MyGeneratedTypes.dll". Поэтому он не может скомпилировать и испускать ошибку компилятора CS0246: "Тип или имя пространства имен" MyGeneratedTypes "не удалось найти (...)".

Насколько я могу судить, мы застряли в этой проблеме, если механизм поставщика типа F # не изменился либо a), чтобы исключить ref для FSharp.Core 4.3, когда он не нужен в сгенерированной сборке, или b) включить ref с метаданными "SpecificVersion:true".

4b9b3361

Ответ 1

Просто добавьте ссылку на FSharp.Core 4.3.0.0 в проект С# (или игнорируйте предупреждение). Несмотря на странное соглашение о нумерации, FSharp.Core 4.3.0.0 не зависит ни о чем в .Net 4.5, это зависит только от .Net 4.0.