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?
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>
.Structure variables cannot be null, one option would be to declare it as nullable.
Use a nullable:
or
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.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 overMyPoint
(closure occurs when there is ayield return
within a block, or when a lambda or anonymous method uses a variable from an enclosing block), then an instance ofPoint
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 100Point
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.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
because structs do not get an implementation of == by default. so you need to overload the == and != operators in your struct like this:
and then :
another option is to use Equals directly: