Giter VIP home page Giter VIP logo

Comments (28)

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Реализация начата в ветке type-distance.

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Меня несколько смущает наличие типа decimal в цепочке преобразований целочисленных типов. @impworks, тут точно всё в порядке?

(С другой стороны, согласен, что только такое его расположение гарантирует преобразование без потери данных.)

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

@impworks, также не описано поведение для преобразования signed / unsigned типов.

from lens.

impworks avatar impworks commented on July 22, 2024

Это правильно. Цомпилятор C# позволяет неявное приведение к decimal только целочисленных типов.

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

В общем, я тут всё запилил. Пока не принято решение по signed, конвертацию unsigned к signed я считаю отдельным шагом, а конвертацию в обратную сторону не разрешаю.

Как только решим что-то с этим вопросом - нужно будет дописать тесты (я пока для таких кейсов их писать не стал). @impworks, заодно проведи ревью моего кода (и особенно - тестов, т.к. в них учтена вся логика расчётов).

from lens.

impworks avatar impworks commented on July 22, 2024

unsigned конвертится к signed вдвое большего размера, да? Это правильно, конвертация в обратную сторону только явная. Сейчас посмотрю.

from lens.

impworks avatar impworks commented on July 22, 2024

Добавил три теста, которые падают.

  1. Расстояние от int[] до object почему-то получается 2, хотя по логике - 1.
  2. Ковариантность массивов, про которую говорил выше.
  3. Приведение примитивных типов: int <- uint и аналогичные ей должны быть запрещены (или нет?).

from lens.

impworks avatar impworks commented on July 22, 2024

P.S. Заодно хотелось бы метод, который бы возвращал наиболее подходящий общий тип для двух числовых. Он будет использоваться для вычисления типа математических операций.

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

unsigned конвертится к signed вдвое большего размера, да?

Нет, я, не подумав, запилил конвертацию к signed-типу того же размера, что ужасно нелогично. Это нужно будет переделать.

Extension-метод для подходящего типа тоже впилю, ок.

from lens.

impworks avatar impworks commented on July 22, 2024

Я забыл еще один краевой случай: value-типы должны приводиться к nullable-форме также за 1 шаг. Залил тест на эту тему.

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Расстояние от int[] до object почему-то получается 2, хотя по логике - 1.

Это соответствует приведённой тобой спецификации. Боксинг считается за 1 только для value-типов. int[] - это наследник Array, который, в свою очередь, является наследником Object. Вот и получается 2.

Это неправильно?

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Ковариантность массивов, про которую говорил выше.

Ты говорил не про ковариантность массивов, а про ковариантность генериков, для параметров которых она правильно указана ;)

Внезапно, массивы вообще не являются генериками. Для них придётся вкрутить костыль. Я поправил спеку в соответствии с этим.

from lens.

impworks avatar impworks commented on July 22, 2024

А, вот оно что - там в промежуте Array. Хорошо, значит поправлю тест.

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Ну, по этой задаче всё готово. @impworks, исправляй тест и будем мержить в master.

Заодно я запилил полезный хелпер IsNullable(this Type type).

from lens.

impworks avatar impworks commented on July 22, 2024

Смерджил, вроде бы все отлично :)

from lens.

impworks avatar impworks commented on July 22, 2024

Ох щи! Забыли один кейс, когда в функцию вместо параметра передается NullType.
От него до любого byref-типа должна быть единица, до Nullable<T> также единица, а для всех остальных - ноль.

from lens.

impworks avatar impworks commented on July 22, 2024

Кроме того, раз мы договорились о том, что decimal не подвержен кастованию, его учет следует также исключить.

from lens.

impworks avatar impworks commented on July 22, 2024

И еще один момент! Я понял, как найти соответствующий оператор приведения:

typeof(SomeType).GetMethods().Where(m => m.Name == "op_Explicit" && m.ReturnType = typeof(ExpectedType)).FirstOrDefault()

Давай добавим такую проверку? Если такой метод существует - то расстояние будет также равно единице. То же самое для op_Implicit.

Я добавлю поддержку этих методов в CastOperatorNode, которая используется практически везде - при вызове, сохранении, инициализации структур и т.д. - соответственно, в этих местах автоматически включится неявное приведение.

from lens.

impworks avatar impworks commented on July 22, 2024

Оказывается, компилятор 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.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Давай добавим такую проверку? Если такой метод существует - то расстояние будет также равно единице. То же самое для op_Implicit.

@impworks, я не уверен, что это целесообразно применительно к op_Explicit - касты не зря же объявлены явными. С ними будут проблемы - например, любые преобразования decimal'ов куда угодно будут выполняться за 1 шаг, т.к. для всех числовых типов объявлены как op_Explicit, так и op_Implicit.

from lens.

impworks avatar impworks commented on July 22, 2024

Хм, пожалуй, ты прав. У меня смешались понятия явного и неявного приведения. А TypeDistance не обязано вычисляться для типов, которые могут быть приведены только явно.

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Кроме того, раз мы договорились о том, что decimal не подвержен кастованию, его учет следует также исключить.

ac86903 - проверь, сделал ли я как нужно. Выкинул decimal отовсюду, теперь кастинг для него поддерживается только стандартный.

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Неявные касты теперь поддерживаются: 7f590de.

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

@impworks, мне не кажется, что такая поддержка кастования Nullable нам действительно нужна. Она только усложнит спеку и сам процесс кастования, однако никакого существенного преимущества нам не даст. Я бы и в коде на C# не догадался такое юзать :)

from lens.

impworks avatar impworks commented on July 22, 2024

Всплыл еще один кейс, на который следует обратить внимание: в generic-методах тип аргументов может быть задан как IEnumerable<TSource>, где TSource - некий тип-плейсхолдер. У него следует проверять свойство BaseType и флаг IsClass.

IEnumerable<TSource> должен одинаково подходить к IEnumerable<> любого типа.

from lens.

impworks avatar impworks commented on July 22, 2024

Дописал кое-что в TypeExtensions.DistanceFrom. Тесты вроде бы проходятся, но все равно, посмотри насколько правильно я сделал? Описано в коммитах: 0f080e1 603a108

from lens.

ForNeVeR avatar ForNeVeR commented on July 22, 2024

Да вроде бы норм.

from lens.

impworks avatar impworks commented on July 22, 2024

Тогда закрываю.

from lens.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.