如何检查结构是否已实例化?

时间:2012-10-01 12:39:26

标签: c# struct null

我有一个结构(为了这个问题的目的)几乎模仿内置的Point类型。

我需要在使用之前检查它是否已经实例化。如果是Point,我可以这样做:

if (this.p == null)

但现在会产生以下错误:

  

运算符'=='无法应用于'ProportionPoint'和'< null>'

类型的操作数

如何将我的结构与null进行比较?还有另一种检查实例化的方法吗?

11 个答案:

答案 0 :(得分:31)

struct是一种值类型 - 它永远不会为空。

您可以检查default(ProportionPoint),这是结构的默认值(例如零)。但是,对于某一点,可能是默认值 - 原点 - 也是“有效”值。

相反,您可以使用Nullable<ProportionPoint>

答案 1 :(得分:14)

结构是值类型,与引用类型相反,它们永远不能为null。您可以检查默认值:

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

答案 2 :(得分:4)

因为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))

答案 3 :(得分:2)

结构不能为空。它是值类型,而不是引用类型。您需要使用默认值检查属性。类似的东西:

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

答案 4 :(得分:2)

结构永远不能为null,因此您无法将其与null进行比较。并且始终初始化结构 - 如果不是,则由编译器使用默认值。

答案 5 :(得分:2)

使用可空:

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

if (!p1.HasValue) ...

答案 6 :(得分:1)

与引用类型的变量或值(对于零或一个该类型的实例的引用)不同,结构变量或值结构实例。如果有一个以{Point myPoint; ...}开头的代码块,并且块中的任何内容都不会在MyPoint内关闭(当块中有yield return时,或者当lambda或匿名时发生关闭方法使用来自封闭块的变量,然后Point的实例将在执行进入块之前的某个时间出现,并且可能在执行离开块之后的任何时间停止存在。在任何可以使用struct-type变量的上下文中,结构都存在。

所有结构类型被视为具有无操作默认构造函数的原因是结构类型隐式存在。当执行类似Point[] myPoints = new Point[100];的语句时,它会创建一个由100个Point结构组成的零填充数组;在此过程中,100零填充的Point实例立即出现。在C ++中,如果类型具有构造函数,则创建该类型的数组将按顺序调用数组的每个元素上的构造函数,然后才能为任何代码提供对该数组的访问权限。如果在构造任何元素时抛出异常,编译器生成的代码将在阵列本身蒸发之前已成功创建的每个元素上运行确定性析构函数。虽然这是一个非常强大的功能,但在.net中包含它会使框架变得非常复杂。

答案 7 :(得分:0)

我制作了一个只适用于结构的扩展方法:

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

调用约定:

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

我知道它并没有真正检查它是null。但是,如果我给它一个更精确的名称,比如IsEmptyIsDefault,在六个月内我会忘记它,并且在看到可用的方法列表时不会选择它。从技术上讲,它不是空检查;但从概念上讲它是。

答案 8 :(得分:0)

您不能在NULL上检查struct,但可以这样检查默认的单位化值:

if (instanceOfYourStruct == default)

答案 9 :(得分:-1)

结构变量不能为null,一个选项是将其声明为可为空。

答案 10 :(得分:-1)

结构不能为空,但如果您确实希望在任何时候存储等效于默认值的值,则根据默认值检查结构的变通方法会给出误报。

(例如,值为(0,0,0)的结构可能是未触及的默认值,或者可能是将原点存储在3D空间中。)

避免这种假阴性问题的另一种方法是将另一个属性添加到结构中 - 例如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;
    }
}