Зажим и округление значения во время неявного преобразования - PullRequest
0 голосов
/ 03 февраля 2019

Я разработал пользовательский целочисленный тип.Вот его определение в C #.

public struct PitchClass
{
    private readonly int value;

    private PitchClass(int value)
    {
        this.value = CanonicalModulus.Calculate(value, 12);
    }

    public static implicit operator PitchClass(int value)
    {
        return new PitchClass(value);
    }

    public static implicit operator PitchClass(double value)
    {
        return new PitchClass((int)Math.Round(value));
    }

    public static implicit operator int(PitchClass pitchClass)
    {
        return pitchClass.value;
    }
}

PitchClass - это int, значения которого находятся в диапазоне [0, 11].

Как вы можете прочитать изВ коде C # значения int и double могут быть неявно преобразованы в PitchClass с помощью оператора канонического модуля :

PitchClass pitchClass = -3;
Console.WriteLine(pitchClass); // 9

Значение double также округляется во время неявногопреобразование:

PitchClass pitchClass = -3.4d;
Console.WriteLine(pitchClass); // 9

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

Почему?Это плохая практика?Если да, есть ли другой способ избежать проверки аргументов для каждой переменной PitchClass в каждом методе?

Спасибо

1 Ответ

0 голосов
/ 03 февраля 2019

Неплохая практика - создавать базовый тип и делать его конвертируемым в другие базовые типы данных.Он также не предназначен для определения неявных и явных преобразований.

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

Если вы намерены интенсивно использовать эту структуру, реализуя IConvertible, IComparable, IEquatable (и методы GetHashCode() & Equals ()) - хорошая идея, потому что это делают почти все собственные типы данных.

Сложный тип приведен в качестве примера пользовательского типа данных в объяснении интерфейса IConvertible и они делают много разных преобразований в и из других типов.

Кроме того, явное преобразование из double в int делает то же самое, что и вы, делая это преобразование сужающимся (может повлечь потерю данных).

...