Comments (28)
Реализация начата в ветке type-distance.
from lens.
Меня несколько смущает наличие типа decimal
в цепочке преобразований целочисленных типов. @impworks, тут точно всё в порядке?
(С другой стороны, согласен, что только такое его расположение гарантирует преобразование без потери данных.)
from lens.
@impworks, также не описано поведение для преобразования signed
/ unsigned
типов.
from lens.
Это правильно. Цомпилятор C# позволяет неявное приведение к decimal только целочисленных типов.
from lens.
В общем, я тут всё запилил. Пока не принято решение по signed
, конвертацию unsigned
к signed
я считаю отдельным шагом, а конвертацию в обратную сторону не разрешаю.
Как только решим что-то с этим вопросом - нужно будет дописать тесты (я пока для таких кейсов их писать не стал). @impworks, заодно проведи ревью моего кода (и особенно - тестов, т.к. в них учтена вся логика расчётов).
from lens.
unsigned
конвертится к signed
вдвое большего размера, да? Это правильно, конвертация в обратную сторону только явная. Сейчас посмотрю.
from lens.
Добавил три теста, которые падают.
- Расстояние от
int[]
доobject
почему-то получается 2, хотя по логике - 1. - Ковариантность массивов, про которую говорил выше.
- Приведение примитивных типов:
int <- uint
и аналогичные ей должны быть запрещены (или нет?).
from lens.
P.S. Заодно хотелось бы метод, который бы возвращал наиболее подходящий общий тип для двух числовых. Он будет использоваться для вычисления типа математических операций.
from lens.
unsigned
конвертится кsigned
вдвое большего размера, да?
Нет, я, не подумав, запилил конвертацию к signed
-типу того же размера, что ужасно нелогично. Это нужно будет переделать.
Extension-метод для подходящего типа тоже впилю, ок.
from lens.
Я забыл еще один краевой случай: value-типы должны приводиться к nullable-форме также за 1 шаг. Залил тест на эту тему.
from lens.
Расстояние от int[] до object почему-то получается 2, хотя по логике - 1.
Это соответствует приведённой тобой спецификации. Боксинг считается за 1 только для value-типов. int[]
- это наследник Array
, который, в свою очередь, является наследником Object
. Вот и получается 2.
Это неправильно?
from lens.
Ковариантность массивов, про которую говорил выше.
Ты говорил не про ковариантность массивов, а про ковариантность генериков, для параметров которых она правильно указана ;)
Внезапно, массивы вообще не являются генериками. Для них придётся вкрутить костыль. Я поправил спеку в соответствии с этим.
from lens.
А, вот оно что - там в промежуте Array
. Хорошо, значит поправлю тест.
from lens.
Ну, по этой задаче всё готово. @impworks, исправляй тест и будем мержить в master
.
Заодно я запилил полезный хелпер IsNullable(this Type type)
.
from lens.
Смерджил, вроде бы все отлично :)
from lens.
Ох щи! Забыли один кейс, когда в функцию вместо параметра передается NullType
.
От него до любого byref-типа должна быть единица, до Nullable<T>
также единица, а для всех остальных - ноль.
from lens.
Кроме того, раз мы договорились о том, что decimal
не подвержен кастованию, его учет следует также исключить.
from lens.
И еще один момент! Я понял, как найти соответствующий оператор приведения:
typeof(SomeType).GetMethods().Where(m => m.Name == "op_Explicit" && m.ReturnType = typeof(ExpectedType)).FirstOrDefault()
Давай добавим такую проверку? Если такой метод существует - то расстояние будет также равно единице. То же самое для op_Implicit
.
Я добавлю поддержку этих методов в CastOperatorNode
, которая используется практически везде - при вызове, сохранении, инициализации структур и т.д. - соответственно, в этих местах автоматически включится неявное приведение.
from lens.
Оказывается, компилятор C# позволяет приводить, например, int?
к float?
. Это делается довольно нетривиальным образом:
// вот такой код:
var a = (int?)null;
var b = (float?)a;
// транслируется в это:
var a = new int?();
var b = a.HasValue ? new float?((float)a.Value) : new float?();
Если это поддерживать (что довольно несложно при переиспользовании нод), то нужно дописать такую возможность в метод определения расстояний.
from lens.
Давай добавим такую проверку? Если такой метод существует - то расстояние будет также равно единице. То же самое для op_Implicit.
@impworks, я не уверен, что это целесообразно применительно к op_Explicit
- касты не зря же объявлены явными. С ними будут проблемы - например, любые преобразования decimal
'ов куда угодно будут выполняться за 1 шаг, т.к. для всех числовых типов объявлены как op_Explicit
, так и op_Implicit
.
from lens.
Хм, пожалуй, ты прав. У меня смешались понятия явного и неявного приведения. А TypeDistance не обязано вычисляться для типов, которые могут быть приведены только явно.
from lens.
Кроме того, раз мы договорились о том, что
decimal
не подвержен кастованию, его учет следует также исключить.
ac86903 - проверь, сделал ли я как нужно. Выкинул decimal отовсюду, теперь кастинг для него поддерживается только стандартный.
from lens.
Неявные касты теперь поддерживаются: 7f590de.
from lens.
@impworks, мне не кажется, что такая поддержка кастования Nullable
нам действительно нужна. Она только усложнит спеку и сам процесс кастования, однако никакого существенного преимущества нам не даст. Я бы и в коде на C# не догадался такое юзать :)
from lens.
Всплыл еще один кейс, на который следует обратить внимание: в generic-методах тип аргументов может быть задан как IEnumerable<TSource>
, где TSource
- некий тип-плейсхолдер. У него следует проверять свойство BaseType
и флаг IsClass
.
IEnumerable<TSource>
должен одинаково подходить к IEnumerable<>
любого типа.
from lens.
Дописал кое-что в TypeExtensions.DistanceFrom
. Тесты вроде бы проходятся, но все равно, посмотри насколько правильно я сделал? Описано в коммитах: 0f080e1 603a108
from lens.
Да вроде бы норм.
from lens.
Тогда закрываю.
from lens.
Related Issues (20)
- Операции над функциями
- Мульти-объявление неинициализированных переменных HOT 1
- Ошибка в грамматике
- Интерфейс контекстно-зависимой типизации
- Ошибка при сохранении сборки - файл занят
- Проблема с тестами Translations HOT 1
- Поддержка атрибута Obsolete
- Поддержка Expression<T>
- Fix continuous integration
- Grammar file gets included after package installing HOT 2
- RegisterFunction doesn't seem to work HOT 1
- Ошибка с замыканием в цикле
- Bad IL format HOT 1
- Verbatim strings
- Наведение порядка в коде HOT 1
- LE3063: Only public, static, non-generic methods can be imported! HOT 4
- Улучшение для вывода типов
- Портирование на .NET Core HOT 4
- Properly detect System.Private library
- RegexNamedGroupsTryParseNoThrow test doesn't work
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lens.