Как я могу реализовать метод с универсальным параметром (ограниченным целочисленным типом) с приведением? - PullRequest
0 голосов
/ 03 марта 2019

Я в основном хочу, чтобы это компилировалось:

T ISqrtN<T>(T N) => (T)Math.Sqrt((double)N);

Тип T будет одним из System.UInt32, System.UInt64 (но, возможно, больше).

Или я будуприходится реализовывать каждый тип ISqrtN отдельно (перегрузка)?

Ответы [ 3 ]

0 голосов
/ 03 марта 2019

C # не поддерживает общие числа.Нет общего числового базового типа и нет интерфейса, объявляющего основные числовые операции.Самый простой способ - перегрузить пользователя

uint ISqrtN(uint N) => (uint)Math.Sqrt((double)N);
ulong ISqrtN(ulong N) => (ulong)Math.Sqrt((double)N);

Тогда IntelliSense явно покажет вам разрешенные типы параметров.Это то, что класс Math делает для Abs или Max, например.

0 голосов
/ 03 марта 2019

Разрешение перегрузки выполняется во время компиляции, даже для универсальных методов.Предпочтительным решением было бы вообще не использовать универсальный метод здесь, поскольку вы не можете ограничить T типами, которые работают, чтобы люди не могли вызывать ISqrtN<DateTime> и т. Д.

Временные решения, поддерживающие универсальный методДля подписи используется либо dynamic привязка во время выполнения:

T ISqrtN<T>(T N) => (T)Math.Sqrt((dynamic)N);

, либо ручная проверка типов и приведение к конкретным поддерживаемым типам:

T ISqrtN<T>(T N)
{
    if (typeof(T) == typeof(uint))
        return (T)(object)(uint)Math.Sqrt((uint)(object)N);
    else if (typeof(T) == typeof(ulong))
        return (T)(object)(ulong)Math.Sqrt((ulong)(object)N);
    else
        throw new ArgumentException();
}

Требуются промежуточные (object) приведения, потому что C #не разрешит прямое приведение от T до uint, но они не будут иметь значения во время выполнения.

0 голосов
/ 03 марта 2019

Вы должны будете реализовать их отдельно.Лучшее, что вы можете сделать, - это использовать ограничение общего типа для значения типа where T : struct, но это позволит отправлять любую структуру.Если вы действительно хотите иметь это ограничение для uint и ulong, я бы рекомендовал оставить исходную реализацию в качестве частного метода и просто создать 2 других открытых метода, каждый из которых предназначен для типа, который вы хотите поддерживать, и заставить их вызыватьприватный метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...