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

11

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

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

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

Ответы:

8

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

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

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

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

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

scrwtp
источник
Но они перечислены как реальные типы, а не псевдонимы типов. Я запутался, потому что 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 #.

Telastyn
источник