Полиморфные числа в .Net и в C #

Очень жаль, что в .Net нет полиморфизма для чисел, то есть нет интерфейса INumeric, который объединяет различные типы числовых типов, такие как bool, byte, uint, int и т. Д. В крайнем случае хотелось бы получить полный пакет абстрактных типы алгебры.

Джо Даффи написал по этому поводу статью:

http://www.bluebytesoftware.com/blog/CommentView,guid,14b37ade-3110-4596-9d6e-bacdcd75baa8.aspx

Как бы вы выразили это на C #, чтобы модернизировать его, не влияя на .Net или C #?

У меня есть одна идея, которая включает в себя сначала определение одного или нескольких абстрактных типов (интерфейсов, таких как INumeric - или более абстрактных, чем это), а затем определение структур, которые реализуют их, и обертывают типы, такие как int, при обеспечении операций, возвращающих новый тип (например, Integer32: INumeric; где сложение определяется как

public Integer32 Add(Integer32 other)
{
    return Return(Value + other.Value);
}

Я немного боюсь скорости выполнения этого кода, но, по крайней мере, он абстрактен.

Никакого перегрузки оператора, доброта ...

Есть другие идеи?

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

Абстракция - это повторное использование.

Обновить:

Это пример сигнатуры типа реализации:

public struct Integer32 : INumeric<Integer32, Int32>, IOrder<Integer32, Int32>

Компенсация отсутствия ковариантных возвращаемых типов.


person Bent Rasmussen    schedule 08.03.2010    source источник
comment
Есть ли причина, по которой вы бы не использовали для этого общий интерфейс? Вы рассматривали и отклоняли дженерики?   -  person overslacked    schedule 09.03.2010
comment
В том-то и дело, я использую дженерики, просто для каждого конкретного типа, такого как Int32, я реализую этот интерфейс в структуре, такой как public struct Integer32: INumeric ‹Integer32, Int32›, ... Странное определение также необходимо к тому факту, что в C # нет ковариантных возвращаемых типов - я считаю, что это термин. В Eiffel возможен синтаксис типа Current. Насколько я понимаю, в C # все иначе.   -  person Bent Rasmussen    schedule 09.03.2010


Ответы (3)


Кто-то уже попытался написать что-то, что может решить вашу проблему. Он называется универсальными операторами и доступен в Разная библиотека утилит.

person Nick    schedule 08.03.2010
comment
Это довольно гениально. А это решение эффективное и производительное? - person Bent Rasmussen; 09.03.2010
comment
@Bent - напрямую о ТТХ говорить не могу. Вам придется исследовать это самостоятельно. - person Nick; 09.03.2010
comment
Спасибо за совет, Ник. Это похоже на C # эквивалент шаблонов C ++ - в некотором роде. Я никогда не думал, что это возможно без макропроцессора. Отличная идея. - person Bent Rasmussen; 09.03.2010
comment
@Brent - Ну ... Обобщения на самом деле ближе всего к шаблонам C ++, которые существуют в C #. Проблема в том, что вы не можете использовать перегруженные операторы в универсальном методе. Упомянутая мною библиотека классов позволяет обойти это ограничение. - person Nick; 09.03.2010
comment
Говоря как Кто-то - да, в целом довольно быстро. Однако сейчас мой Reflection.Emit намного сильнее, так что, возможно, я перенесу его на .NET 2.0. Это определенно быстрее, чем dynamic, особенно когда задействовано Nullable<T> (dynamic значительно замедляется). - person Marc Gravell; 09.03.2010
comment
Я хотел бы провести некоторые сравнения между вашей техникой динамической компиляции и техникой обертывания структур, которую я применяю. - person Bent Rasmussen; 09.03.2010
comment
@Nick Я не считаю дженерики очень сопоставимыми с шаблонами - они достигают некоторых из тех же вещей, но шаблоны кажутся более выразительными, но менее семантически кошерными в том смысле, что это своего рода синтаксическое преобразование, которое затем проверяется, чтобы увидеть, имеет ли это смысл. Я, кажется, помню, что в шаблонах C ++ ошибки не дают вам лучших диагностических сообщений. Но да, в каком-то смысле вы можете сравнить их - но я думаю, что техника Марка ближе к шаблонам C ++, потому что это своего рода отдельная фаза компиляции. Но пока это быстро ... - person Bent Rasmussen; 09.03.2010

Команда разработчиков csharp уже занимается этим. Если вы хотите получить представление о будущем классов типов в C #, начните читать с

https://github.com/dotnet/csharplang/issues/164

введите описание изображения здесь

Кажется, его поддерживает Мэдс Торгессон, так что это не просто случайный пост странствующего фаната Haskell.

Приведенный пример класса типов или формы на языке C #:

public shape SGroup<T>
{
    static T operator +(T t1, T t2);
    static T Zero { get; }
}

обратите внимание, это не похоже на интерфейс. Он объявляет статический метод, принадлежащий SGroup. Читайте подробности и обсуждения.

person bradgonesurfing    schedule 17.07.2017

Если вы планируете использовать C # 4.0, вы можете легко моделировать общие математические операции, используя dynamic. Вот пример простой функции сложения (для получения дополнительной информации см. Этот блог):

public static T Add<T>(T a, T b) {
  dynamic ad = a;
  dynamic bd = b;
  return ad + bd;
}

Я не играл с этим, поэтому не могу много сказать о спектакле. Безусловно, будет некоторая цена за использование динамических функций, но я думаю, что DLR сможет выполнять очень эффективную оптимизацию, если вы будете вызывать эту функцию несколько раз. Фактически, я не удивлюсь, если он будет иметь профиль производительности, аналогичный упомянутым выше универсальным операторам.

person Tomas Petricek    schedule 09.03.2010
comment
Повторная производительность - когда я проверял довольно раннюю бета-версию, было заметное замедление, если T оказалось Nullable<X> для некоторых X, но в остальном это было не слишком плохо (для умеренного использования как минимум). - person Marc Gravell; 09.03.2010
comment
Да, я знаю об этом, но динамика просто слишком медленная, это убийца производительности. - person Bent Rasmussen; 09.03.2010
comment
... Ну, я думаю, что это ... И не люблю вот так обманывать систему шрифтов. - person Bent Rasmussen; 09.03.2010
comment
Боюсь, вы все равно обманете систему типов. Общие операторы в этом смысле почти такие же. В F # вы можете использовать статические ограничения (разрешенные во время компиляции), которые не обманывают (но имеют другие ограничения), или числовые ассоциации, которые похожи на Generic Операторы. См., Например: stackoverflow.com/questions/ 2225949 / - person Tomas Petricek; 09.03.2010
comment
@ Томас: Спасибо. Я очень впечатлен единицами измерения F # и некоторыми другими его аспектами. - Однако я предпочитаю подход C #, более ориентированный на моделирование. - person Bent Rasmussen; 10.03.2010