Почему F # Core определяет универсальные типы массивов?


11

Я только что заметил, что пространство имен FSharp.Core включает в себя универсальные типы массивов до 4 измерений, то есть Core. [] <'T> , Core. [,] <' T> и т. Д. C # и VB, кажется, работают очень хорошо с System.Array - хотя мне не ясно, как им удается поддерживать строго типизированные специализированные типы массивов, такие как int [], string [].

Я думаю, что это становится двумя вопросами тогда:

  • Как C # поддерживает строго типизированные специализированные типы массивов, такие как int [], основанные на неуниверсальном System.Array?
  • Учитывая, что C # удается это сделать, почему F # определяет универсальные типы массивов?

Ответы:


8

F # не определяет общие типы массивов как таковые. Массивы в F # - это тот же тип массива, который используется в .NET, и, несмотря на все синтаксические свидетельства, указывающие на обратное, они не являются общими.

Иногда это может иметь неприятные последствия для вас, когда вы используете отражение в F # - даже если у вас есть array<int>совершенно правильный тип универсального типа, когда вы проверяете его, вы получаете ложь от IsGenericType, истину от IsArrayи вы получаете аргумент типа с , GetElementTypeа затем GetGenericArguments.

Как отметил Теластин в своем ответе, это, скорее всего, устаревший багаж .NET 1.0, с которым нам придется жить. Но это всего лишь одна из многих вещей, которые делают использование API отражения в F # настоящим минным полем.

Что определяет F #, так это [], [,] ...сокращения типов / псевдонимы / операторы и модули с соответствующими функциями, но все они в конечном итоге ссылаются на один и тот же тип массива ниже.

Вы можете посмотреть исходный код на github здесь и здесь, чтобы убедиться в этом.


Но они перечислены как реальные типы, а не псевдонимы типов. Я запутался, потому что msdn.microsoft.com/en-us/library/dd233214.aspx говорит: «Тип всех массивов F # - это массив типов .NET Framework», но тогда какова связь между System.Array и FSharp .Core общие массивы?
— Асик

Универсальных массивов нет;) Они могут быть технически реальными типами, и именно поэтому генератор msdn doc их подобрал, но все, что они определяют, это то, как компилятор должен их расширять, если я правильно прочитал (первый файл, на который я ссылался) и пара методов расширения во втором файле. Это все, что нужно сделать. Создайте один из них и вызовите GetType. Это будет специализированный тип массива, основанный на System.Array.
— scrwtp

Или, скорее, сами статические типы являются общими, но тип массива среды выполнения, который они переносят, не является. Может быть, реализовать вывод типа немного проще, но это дикая догадка.
— scrwtp

5

Как C # поддерживает строго типизированные специализированные типы массивов, такие как int [], основанные на неуниверсальном System.Array?

Скорее всего, путем генерации специализированного класса, который наследуется, System.Arrayпоскольку дженерики не были доступны в 1.0. Поведение, вероятно, было сохранено для совместимости.

Учитывая, что C # удается это сделать, почему F # определяет универсальные типы массивов?

Потому что у F # не было тех же ограничений совместимости, которые были у C # 2.0 с существующим кодом. Исходя из того, что я знаю, C # 2.0 имел бы универсальные типы массивов, если бы это был первый выпуск C #.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.