如何检查结构是否已实例化?
我有一个结构(为了这个问题的目的)几乎模仿内置的Point
类型。
我需要在使用它之前检查它是否已被实例化。 当它是Point
,我可以这样做:
if (this.p == null)
但是现在会产生以下错误:
运算符’==’不能应用于’ProportionPoint’和”类型的操作数
如何将我的结构与null进行比较? 还有另一种检查实例化的方法吗?
struct
是一种值类型 – 它永远不会为空。
您可以检查default(ProportionPoint)
,它是结构的默认值(例如零)。 但是,对于某一点,可能是默认值 – 原点 – 也是“有效”值。
相反,您可以使用Nullable
。
结构是值类型,与引用类型相反,它们永远不能为null。 您可以检查默认值:
if (this.p.Equals(default(ProportionPoint)))
因为p是struct它永远不会为null所以你应该将它与它的默认值进行比较。 为了检查您的值和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))
结构不能为空 。 它是一个值类型 ,而不是引用类型。 您需要使用默认值检查属性。 就像是:
if(pX == 0 && pY == 0)
结构永远不能为null,因此您无法将其与null进行比较。 并且始终初始化结构 – 如果不是,则由编译器使用默认值。
使用可空的:
ProportionPoint? p1 = null; if (p1 == null) ...
要么
if (!p1.HasValue) ...
与引用类型的变量或值不同,引用类型是对该类型的零个或一个实例的引用 ,结构变量或值是结构实例。 如果有一个代码块以{Point myPoint; ...}
开头{Point myPoint; ...}
{Point myPoint; ...}
,并且块中的任何内容都不会关闭MyPoint
(当块内有yield return
时,或者当lambda或匿名方法使用封闭块中的变量时,会发生闭包),然后Point
的实例将进入在执行进入块之前的某个时间存在,并且在执行离开块之后的任何时间都可能不再存在。 在任何可以使用struct-type变量的上下文中,结构都存在。
所有结构类型被视为具有无操作默认构造函数的原因是结构类型隐式存在。 当一个人执行像Point[] myPoints = new Point[100];
这样的语句时Point[] myPoints = new Point[100];
,它创建了一个零填充的100 Point
结构数组; 在这个过程中, 100
零填充点实例立即出现。 在C ++中,如果一个类型有一个构造函数,那么在任何代码被赋予对该数组的访问权限之前,创建该类型的数组将按顺序调用该数组的每个元素上的构造函数。 如果在构造任何元素时抛出exception,编译器生成的代码将在arrays本身蒸发之前已成功创建的每个元素上运行确定性析构函数。 虽然这是一个非常强大的function,但在.net中包含它会使框架大大复杂化。
我做了一个只适用于结构的扩展方法:
public static bool IsNull(this T source) where T:struct { return source.Equals(default(T)); }
召集会议:
if(myStruct.IsNull()) DoSomething();
我知道它并没有真正检查它是否为null
。 但是,如果我给它一个更准确的名字,比如IsEmpty
或IsDefault
,在六个月内我会忘记它在那里,看到可用的方法列表不会选择它。 从技术上讲,它不是空检查; 但从概念上讲是这样的。
结构变量不能为null,一个选项是将其声明为可空。
结构不能为空,但如果您确实希望在任何时候存储等效于默认值的值,则根据其默认值检查结构的变通方法可能会给出误报。
(例如,具有值(0,0,0)
可以是未触及的默认值,或者它可以将原点存储在3D空间中。)
另一种避免这种假阴性问题的方法是将另一个属性添加到结构中 – 例如bool或int – 以跟踪数据是否实际存储在其中。 然后让任何构造函数初始化结构,并使用实际数据将此值设置为true / 1。 在默认结构中,此值仍为false / 0,因此即使存储在其中的所有其他数据与默认值匹配,对默认值default(MyStruct)
检查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; } }