Существует ли универсальное ограничение C# для типов “вещественного числа”? [дубликат]

Нет, alert() только позволяет простой текст. Так \n разрыв строки.

21
задан Community 23 May 2017 в 12:32
поделиться

7 ответов

Вы не можете определить такое ограничение, но можете проверить тип во время выполнения. Однако это не поможет вам при выполнении вычислений.

Если вы хотите выполнять вычисления, можно использовать что-то вроде этого:

class Calculations<T, S> where S: Calculator<T>, new()
{
    Calculator<T> _calculator = new S();

    public T Square(T a)
    {
        return _calculator.Multiply(a, a);
    }

}

abstract class Calculator<T>
{
    public abstract T Multiply(T a, T b);
}

class IntCalculator : Calculator<int>
{
    public override int Multiply(int a, int b)
    {
        return a * b;
    }
}

Аналогичным образом определите FloatCalculator и любые необходимые операции. Это не особенно быстро, хотя и быстрее, чем конструкция C # 4.0 dynamic .

var calc = new Calculations<int, IntCalculator>();
var result = calc.Square(10);

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

Это в основном то, о чем Хейлсберг имел в виду в интервью , где проблема обсуждается. Лично мне еще хотелось бы увидеть какой-нибудь базовый тип :)

16
ответ дан 29 November 2019 в 20:43
поделиться

Это известная проблема, поскольку ни один из арифметических классов не принадлежит к одному классу. Таким образом, вы не можете ограничить его.

Единственное, что вы могли бы сделать, это

where T : struct

, но это не совсем то, что вам нужно.

Вот ссылка на конкретную проблему.

Арифметические типы, такие как int, double, decimal должен реализовывать IArithmetic

7
ответ дан 29 November 2019 в 20:43
поделиться

Вы действительно можете это сделать, хотя решение утомительно настраивать и может сбивать с толку разработчиков, которые не знают, почему это было сделано. (так что, если вы решите сделать это, тщательно задокументируйте это!) ...

Создайте две структуры, называемые, скажем, MyInt и MyDecimal, которые действуют как фасады для основных типов CTS Int32 и Decimal (они содержат внутреннее поле соответствующий тип.) У каждого должен быть ctor, который принимает экземпляр типа Core CTS в качестве входного параметра.

Сделайте так, чтобы каждый из них реализовывал пустой интерфейс с именем INumeric

Затем в ваших общих методах сделайте ограничение на основе на этом интерфейсе. С другой стороны, везде, где вы хотите использовать эти методы, вам нужно создать экземпляр соответствующего настраиваемого типа вместо типа Core CTS и передать этот настраиваемый тип методу.

ПРИМЕЧАНИЕ: кодирование настраиваемых структур для правильной эмуляции всего поведения основных типов CTS - утомительная часть ... Вам необходимо реализовать несколько встроенных интерфейсов CLR (IComparable и т. Д.) И перегрузить всю арифметику, и логические операторы ...

3
ответ дан 29 November 2019 в 20:43
поделиться

This might be helpful. You have to use a generic class to achieve what you want.

0
ответ дан 29 November 2019 в 20:43
поделиться

В настоящее время C # не допускает ограничений типов для типов значений. Я задал связанный с этим вопрос не так давно.

Ограничения типа Enum в C #

0
ответ дан 29 November 2019 в 20:43
поделиться

Разве это не подойдет для отдельных классов, реализующих IPoint?

Что-то вроде:

public interface IPoint<T>  
{
    T X { get; set; }
    T Y { get; set; }
}

public class IntegerPoint : IPoint<int>
{

    public int X { get; set; }
    public int Y { get; set; }
}

Поскольку вычисления в любом случае должны отличаться в каждой реализации, верно?

Дэн #

0
ответ дан 29 November 2019 в 20:43
поделиться

Это очень частый вопрос; если вы используете .NET 3.5, это широко поддерживается в MiscUtil через класс Operator , который поддерживает встроенные типы и любые пользовательские типы с операторами (включая "операторы"); в частности, это позволяет использовать с дженериками , например:

public static T Sum<T>(this IEnumerable<T> source) {
    T sum = Operator<T>.Zero;
    foreach (T value in source) {
        if (value != null) {
            sum = Operator.Add(sum, value);
        }
    }
    return sum;
}

Или в другом примере; Сложный

12
ответ дан 29 November 2019 в 20:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: