Подтвердить что ты не робот

Как проверить, была ли создана структура?

У меня есть структура, которая (для целей этого вопроса) в значительной степени имитирует встроенный тип Point.

Мне нужно проверить, что он был создан, прежде чем использовать его. Когда это было Point, я мог бы сделать это:

if (this.p == null)

Но теперь возникает следующая ошибка:

Оператор '==' не может применяться к операндам типа "ProportionPoint" и "<null> "

Как я могу сравнить свою структуру с нулевым? Есть ли другой способ проверить наличие экземпляра?

4b9b3361

Ответ 1

A struct - тип значения - он никогда не является нулевым.

Вы можете проверить значение default(ProportionPoint), которое является значением по умолчанию для структуры (например, ноль). Однако для точки может оказаться, что значение по умолчанию - начало - также является "действительным" значением.

Вместо этого вы можете использовать Nullable<ProportionPoint>.

Ответ 2

structs - типы значений, и они никогда не могут быть нулевыми, противоположными типам ссылок. Вы можете проверить значение по умолчанию:

if (this.p == default(ProportionPoint))

Ответ 3

потому что p является структурой, которая никогда не будет нулевой, поэтому вы должны сравнить ее с ее значением по умолчанию. Чтобы проверить эквивалентность между вашим значением и значением dafault.  Если вы используете ==, вы получите

cannot be applied to operands of type 'ProportionPoint' and 'ProportionPoint' error

потому что структуры не получают реализацию == по умолчанию. поэтому вам нужно перегрузить операторы == и!= в вашей структуре следующим образом:

public static bool operator ==(firstOperand op1,  secondOperand2 op2) 
{
    return op1.Equals(op2);
}

public static bool operator !=(firstOperand op1,  secondOperand2 op2) 
{
   return !op1.Equals(op2);
}

а затем:

if (this.p == default(ProportionPoint))

другой вариант - использовать Equals напрямую:

f (this.p.Equals.default(ProportionPoint))

Ответ 4

A struct не может быть null. Его тип значения, а не ссылочный тип. Вам нужно проверить свойства со значениями по умолчанию. Что-то вроде:

if(p.X == 0 && p.Y == 0)

Ответ 5

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

Ответ 6

Используйте значение nullable:

ProportionPoint? p1 = null;
if (p1 == null) ...

или

if (!p1.HasValue) ...

Ответ 7

В отличие от переменной или значения ссылочного типа, который является ссылкой, к нулю или одному экземпляру этого типа, структурная переменная или значение представляет собой экземпляр структуры, Если у вас есть блок кода, который начинается с {Point myPoint; ...}, и ничто в блоке не закрывается над MyPoint (закрытие происходит, когда в блоке есть yield return или когда лямбда-или анонимный метод использует переменную из вложенный блок), то экземпляр Point появится как-то до того, как выполнение запустится в блок и может перестать существовать в любое время после того, как выполнение покидает блок. В любом контексте, где можно использовать переменную типа struct, структура существует.

Причина, по которой все типы структуры рассматриваются как имеющие конструктор по умолчанию, созданный не по умолчанию, заключается в том, что типы структуры возникают неявно. Когда вы выполняете оператор типа Point[] myPoints = new Point[100];, он создает нулевой набор из 100 Point структур; при этом 100 нулевые заполненные экземпляры Point мгновенно появляются. В С++, если у типа есть конструктор, создание массива этого типа вызовет конструктор по каждому элементу массива последовательно, прежде чем любому коду будет предоставлен доступ к массиву через некоторое время. Если при построении любого элемента генерируется исключение, код, сгенерированный компилятором, будет запускать детерминированный деструктор для каждого элемента, который был успешно создан до того, как сам массив испарится. Хотя это очень мощная функция, в том числе и внутри .net, существенно осложнила бы Framework.

Ответ 8

Структурные переменные не могут быть нулевыми, один параметр должен объявить его как nullable.

Ответ 9

Я сделал метод расширения, который работает только с structs:

public static bool IsNull<T>(this T source) where T:struct
{
  return source.Equals(default(T));
}

Соглашение о звонках:

if(myStruct.IsNull())
  DoSomething();

Я понимаю, что он не проверяет, если он null. Однако, если я дал ему более точное название, например IsEmpty или IsDefault, через шесть месяцев я бы забыл его там и, увидев список доступных методов, не выбирайте его. Это не технически нулевая проверка; но концептуально это.

Ответ 10

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

(Например, структура со значением (0,0,0) может быть нетронутым по умолчанию или может хранить точку начала в трехмерном пространстве.)

Другой подход, позволяющий избежать этой ложноотрицательной проблемы, состоял бы в том, чтобы просто добавить другое свойство к структуре - например, bool или int - отслеживать, действительно ли данные были сохранены в нем. Тогда у любого конструктора, который инициализирует структуру с фактическими данными, установите это значение в true/1. В структуре по умолчанию это значение по-прежнему будет false/0, поэтому проверка на default(MyStruct) никогда не должна давать ложный отрицательный результат, даже если все остальные данные, хранящиеся в нем, соответствуют значениям по умолчанию.

public Struct MyStruct { 
    public float x { get; private set; }
    public bool initialized { get; private set; }

    public MyStruct(float _x){
        x=_x;
        initialized = true;
    }
}