Нарушение взаимодействия в .NET? - PullRequest
4 голосов
/ 03 апреля 2009

Недавно я задал вопрос об использовании расширений F # в C #. Брайан процитировал:

Согласно спецификации языка, раздел 10.7 «Расширения типов»:

Дополнительные элементы расширения являются синтаксическим сахаром для статических элементов. Использование опциональных расширенных членов упрощает обращение к статическим членам с закодированными именами, где объект передается в качестве первого аргумента. Кодировка имен не указана в этом выпуске F # и не совместима с C # кодировками членов расширения C #.

Мне интересно, есть ли другие проблемы с совместимостью в .NET, которые ограничивают использование некоторых функций некоторыми языками, но не другими?

Ответы [ 4 ]

6 голосов
/ 03 апреля 2009

Я ожидаю, что есть много вещей, но в основном в угловых случаях, если вы говорите об основных управляемых языках (C #, VB и скоро F #). Другие случаи, когда F # в настоящее время плохо взаимодействует с C #, это когда перегрузки методов, которые принимают и Action, и Func (разрешение перегрузки C # работает иначе, чем F #, поэтому вызовы F # для такого API могут быть более многословными); массивы аргументов 'params' (особенно при попытке воспользоваться преимуществом 'ковариации массива', которая является функцией C #, но не F #); Есть некоторые проблемы, связанные с созданием подклассов или реализацией интерфейсов в сочетании с доступностью (например, общедоступной и внутренней), когда иногда вы не можете получить класс F # из C # one ...

Многие из этих проблем являются либо просто «ошибками» в компиляторе F # CTP, либо «проблемами проектирования» со спецификацией языка F #, которые могут быть изменены до окончательного выпуска F #.

Я не очень хорошо знаю пыльные углы CLR, но держу пари, что есть места, где C # и VB не могут мешать. И есть функции CLR, которые не использует ни один из основных языков, поэтому я ожидаю, что есть способы создать действительный IL, который может вызвать проблемы с некоторым взаимодействием.

В целом, я думаю, что все эти вещи незначительны, и в случае с F # часть этого будет «исправлена» перед финальным выпуском. Но мне будет любопытно посмотреть, что другие люди вызывают, так как это может быть полезным отзывом для команд управляемых языков в MS.

2 голосов
/ 20 августа 2009

C ++ / CLI имеет семантику «передача по значению» для объектов CLR (не ссылок, а самих объектов), в комплекте с конструкторами копирования, временными файлами и их уничтожением и т. Д.

ref class Foo {
public:
  Foo() { ... }
  Foo(Foo% other) { ... }
};

и затем:

Foo^ getFooRef() { ... } // returns a reference to Foo
Foo getFoo() { ... } // returns a copy of Foo

Конечно, на уровне CLR это все ссылки - C ++ / CLI имитирует семантику копирования, вызывая конструкторы operator= и деструкторы в моменты, когда вы ожидаете, что они будут вызваны. В случае «возврата по значению» это означает, что вызывающая сторона должна будет правильно уничтожить объект, ссылку на который он получает. Ни C #, ни VB, ни какой-либо другой язык CLI, кроме C ++ / CLI, не знают, как это сделать, поэтому такие методы не могут быть вызваны из них.

Еще одним интересным моментом является то, что CLR позволяет определять методы с ref возвращаемыми типами. Ни один язык CLR не поддерживает их (даже C ++ / CLI), но вы можете написать код вручную в MSIL, и он не будет вызываться из любого другого языка.

В общем, именно из-за этого и была разработана спецификация общего языка (CLS). Если вы будете придерживаться его правил, у вас не должно быть проблем с совместимостью ни с одним языком.

2 голосов
/ 03 апреля 2009

Существует набор рекомендаций , выпущенных Microsoft для работы с подобными вещами. По сути, это для разработчиков классов и включает в себя предложения, такие как исключение методов, которые отличаются только регистром (для языков без учета регистра, таких как VB), предоставление альтернативных методов для операторов, когда перегрузка операторов может быть недоступна и т. Д.

1 голос
/ 20 августа 2009

Использование f # классов из кода c # может быть сложным или раздражающим время от времени.

События в f # не являются «нормальными» событиями по умолчанию

Добавление атрибута [<CLIEvent>] решает эту проблему, но если вы не используете DelegateEvent вместо Event, код c # должен ссылаться на FSharpCore .

Отличия функции первого класса

Создать делегат из FastFunc (основной функции f #) в f # легко. Создание FastFunc из делегата в c # довольно раздражает, и здесь затронут . В частности, концепция Unit очень плохо отображается в c # и мире делегатов Func / Action.

Операторы

Операторы, определенные в f #, плохо, и непоследовательно , обрабатываются в других языках CLR. Это неизбежный результат того, что CLR не определяет требуемый тип метаданных сложного типа.
Операторы должны рассматриваться как особенности языка и не должны хорошо переводить между разными языками. Любой полезный оператор должен иметь эквивалентный статический метод, который обеспечивает согласованные и переносимые средства доступа к функциональности.

Тип логического вывода

В f # это широко распространено, и в результате вы можете найти несколько очень сложных типов, которые создаются. После использования в c # это может стать громоздким, так как вывод типов на функции не так мощен, но, что еще хуже, он полностью отсутствует в конструкторах, что может привести к мучительно многословному коду на c #.

...