How can I check whether a struct has been instanti

2019-02-11 13:03发布

I have a struct that (for the purposes of this question) pretty much mimics the built in Point type.

I need to check that it has been instantiated before using it. When it was Point, I could do this:

if (this.p == null)

But that now generates the following error:

Operator '==' cannot be applied to operands of type 'ProportionPoint' and '<null>'

How can I compare my struct against null? Is there another way to check for instantiation?

标签: c# struct null
10条回答
贼婆χ
2楼-- · 2019-02-11 13:06

A struct is a value type - it's never null.

You can check against default(ProportionPoint), which is the default value of the struct (e.g. zero). However, for a point, it may be that the default value - the origin - is also a "valid" value.

Instead you could use a Nullable<ProportionPoint>.

查看更多
相关推荐>>
3楼-- · 2019-02-11 13:18

Structure variables cannot be null, one option would be to declare it as nullable.

查看更多
走好不送
4楼-- · 2019-02-11 13:19

Use a nullable:

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

or

if (!p1.HasValue) ...
查看更多
相关推荐>>
5楼-- · 2019-02-11 13:20

Structs can't be null, but the workaround of checking a struct against its default can give a false negative if you actually want to store values equivalent to the defaults in it at any point.

(For example, a struct with the value (0,0,0) could be an untouched default, or it could be storing the origin point in 3D space.)

Another approach that avoids this false negative issue would be to just add another property to the struct - e.g. a bool or int - to track whether data has actually been stored in it. Then have any constructor that initializes the struct with actual data set this value to true/1. In the default struct, this value will still be false/0, so checking against default(MyStruct) should never give you a false negative even if all other data stored in it matches the default values.

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

    public MyStruct(float _x){
        x=_x;
        initialized = true;
    }
}
查看更多
Animai°情兽
6楼-- · 2019-02-11 13:21

Unlike a variable or value of a reference type, which is a reference to either zero or one instances of that type, a struct variable or value is a struct instance. If one has a block of code which starts with {Point myPoint; ...}, and nothing in the block closes over MyPoint (closure occurs when there is a yield return within a block, or when a lambda or anonymous method uses a variable from an enclosing block), then an instance of Point will come into existence sometime before execution enters the block, and may cease to exist at any time after execution leaves the block. In any context where one can make use of a struct-type variable, the structure exists.

The reason one all structure types are regarded as having a do-nothing default constructor is that structure types come into existence implicitly. When one performs a statement like Point[] myPoints = new Point[100];, it creates a zero-filled array of 100 Point structures; in the process, 100 zero-filled Point instances instantly come into existence. In C++, if a type has a constructor, creating an array of that type will call the constructor on every element of the array in sequence before any code is given access to the array as a while. If an exception is thrown while constructing any element, compiler-generated code will run the deterministic destructor on every element which had been successfully created before the array itself evaporates. While this is a very powerful feature, including it within .net would have substantially complicated the Framework.

查看更多
beautiful°
7楼-- · 2019-02-11 13:24

because p is struct it never be null so you should compare it to it's default value. In order to check equivalence between your value and dafault value. If you use == you will get

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

because structs do not get an implementation of == by default. so you need to overload the == and != operators in your struct like this:

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

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

and then :

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

another option is to use Equals directly:

f (this.p.Equals.default(ProportionPoint))
查看更多
登录 后发表回答