Структуры с ограничениями - PullRequest
       26

Структуры с ограничениями

2 голосов
/ 01 августа 2009

Мне было трудно понять, как я могу написать struct на C #, который имеет ограничения на значения его полей. Например, System.DateTime

DateTime d = new DateTime();

устанавливает значение 01/01/0001 12:00:00 AM в d . Но я не могу написать явный беспараметрический конструктор, поскольку struct s не может иметь явный беспараметрический конструктор. Итак, как я могу создать struct , которая будет построена по умолчанию в рамках ограничений, которые я хочу?

Единственное, о чем я мог подумать, это спроектировать свойства так, чтобы они возвращали значения в рамках ограничений, которые я хочу. Например, если я храню значение int , которое я хочу, чтобы оно было больше 0, я просто добавляю единицу к возвращаемому значению и не позволяю установить значение меньше 1. Это разумный путь?

Ответы [ 7 ]

3 голосов
/ 01 августа 2009

См. Ответ на этот вопрос для получения дополнительной информации. По сути, без параметров поля типов значений всегда инициализируются значениями по умолчанию в качестве оптимизации производительности, поскольку типы значений часто используются в больших количествах в массивах и т. Д.

Вам следует подумать о создании класса, если вы хотите установить ограничения true , но «умные свойства» могут быть хорошим способом, если при использовании вашего класса возникает вопрос о производительности. Что касается типа DateTime, то да, он делает «умные» свойства, сохраняя дату как число, которое по запросу преобразуется в определенный формат (доступ через свойства). 01/01/0001 12:00:00 AM фактически является представлением внутреннего 0 по умолчанию в соответствии с дизайном.

2 голосов
/ 01 августа 2009

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

1 голос
/ 01 августа 2009

Вам нужна семантика типа значения? Что не так с простым старым неизменным классом?

0 голосов
/ 01 августа 2009

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

так ...

public struct BetweenNegativeFiveAndFive
{
    public static readonly int MinValue;
    public static readonly int MaxValue;
    int _value;
    public int Value
    {
        get { return _value; }
    }
    public int Add(int a)
    {
        int b = _value + a;
        if (b >= MinValue && b <= MaxValue)
            _value = b;
        return _value;
    }
    static Foo()
    {
        MinValue = -5;
        MaxValue = 5;
    }
}
0 голосов
/ 01 августа 2009

DateTime устанавливает значение по умолчанию DateTime.Min. Когда вы распечатываете его (что относится к его методу ToString ()), печатается его текущее значение.

Вот пример:

class Program
{
    static void Main(string[] args)
    {
        ChrisTime t = new ChrisTime();
        Console.WriteLine(t);

        DateTime time = new DateTime();
        Console.WriteLine(time);

        Console.Read();
    }
}

public struct ChrisTime
{
    private int _length;

    public int Length
    {
        get
        {
            return _length;
        }
        set
        {
            _length = value;
        }
    }

    public override string ToString()
    {
        return Length.ToString();
    }

}

Распечатывает:

0
01/01/0001 00:00:00

Но если вы попытаетесь инициализировать _length в 1, произойдет сбой, так как вы не можете этого сделать и установить конструкторы. Однако метод ToString DateTime выполняет:

public override string ToString()
{
    return DateTimeFormat.Format(this, null, DateTimeFormatInfo.CurrentInfo);
}

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

0 голосов
/ 01 августа 2009

Часть семантики типа значения в CLR заключается в том, что тип значения всегда имеет разумное допустимое значение по умолчанию (и, кроме того, это разумное значение по умолчанию представлено инициализированным по умолчанию типом значения с использованием обычных правил инициализации). Если это не относится к вашему типу, то это не должно быть struct.

0 голосов
/ 01 августа 2009

Я рекомендую использовать Reflector , чтобы точно узнать, как была написана структура DateTime. Это должно дать вам понимание, которое вам нужно.

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