C# 如何检查结构是否已实例化?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12673440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I check whether a struct has been instantiated?
提问by Tom Wright
I have a struct that (for the purposes of this question) pretty much mimics the built in Pointtype.
我有一个结构体(就这个问题而言)非常模仿内置Point类型。
I need to check that it has been instantiated before using it. When it was Point, I could do this:
在使用它之前,我需要检查它是否已被实例化。当它是Point,我可以这样做:
if (this.p == null)
But that now generates the following error:
但是现在会产生以下错误:
Operator '==' cannot be applied to operands of type 'ProportionPoint' and '<null>'
运算符“==”不能应用于“ProportionPoint”和“<null>”类型的操作数
How can I compare my struct against null? Is there another way to check for instantiation?
如何将我的结构与 null 进行比较?有没有另一种方法来检查实例化?
采纳答案by Rawling
A structis a value type - it's never null.
Astruct是一种值类型——它永远不会为空。
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.
您可以检查default(ProportionPoint),这是结构的默认值(例如零)。但是,对于某一点,默认值(原点)可能也是“有效”值。
Instead you could use a Nullable<ProportionPoint>.
相反,您可以使用Nullable<ProportionPoint>.
回答by Habib
A struct can't be null. Its a value type, not a reference type. You need to check against the properties with the default values. Something like:
一个结构不能为空。它是一个值类型,而不是一个引用类型。您需要检查具有默认值的属性。就像是:
if(p.X == 0 && p.Y == 0)
回答by SomebodyYouKnow
A struct can never be null, so you can't compare it to null. And a struct is always initialized - if not by you, then by the compiler with default values.
结构永远不能为空,因此您无法将其与空值进行比较。并且一个结构总是被初始化——如果不是由你初始化,那么由具有默认值的编译器初始化。
回答by Darin Dimitrov
structs are value types and they can never be null contrary to reference types. You could check against the default value:
结构体是值类型,与引用类型相反,它们永远不能为空。您可以检查默认值:
if (this.p.Equals(default(ProportionPoint)))
回答by Thorsten Dittmar
Use a nullable:
使用可空值:
ProportionPoint? p1 = null;
if (p1 == null) ...
or
或者
if (!p1.HasValue) ...
回答by supercat
Unlike a variable or value of a reference type, which is a referenceto either zero or one instances of that type, a struct variable or value isa 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 returnwithin a block, or when a lambda or anonymous method uses a variable from an enclosing block), then an instance of Pointwill 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.
与引用类型的变量或值不同,它是对该类型的零个或一个实例的引用,结构变量或值是结构实例。如果有一个以 开头的代码块{Point myPoint; ...},并且该块中的任何内容都没有关闭MyPoint(当yield return块内有 a 时,或者当 lambda 或匿名方法使用来自封闭块的变量时,就会发生关闭),则Pointwill的实例在执行进入块之前的某个时间存在,并且可能在执行离开块后的任何时间停止存在。在任何可以使用结构类型变量的上下文中,该结构都存在。
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 Pointstructures; in the process, 100zero-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.
所有结构类型都被视为具有无用默认构造函数的原因是结构类型隐式存在。当执行类似 的语句时Point[] myPoints = new Point[100];,它会创建一个由 100 个Point结构组成的零填充数组;正在进行中,100零填充的 Point 实例立即出现。在 C++ 中,如果类型具有构造函数,则创建该类型的数组将在任何代码暂时访问数组之前按顺序对数组的每个元素调用构造函数。如果在构造任何元素时抛出异常,编译器生成的代码将对在数组本身消失之前成功创建的每个元素运行确定性析构函数。虽然这是一个非常强大的功能,但将它包含在 .net 中会使框架变得非常复杂。
回答by Technovation
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
因为 p 是 struct 它永远不会为 null 所以你应该将它与它的默认值进行比较。为了检查您的值和 dafault 值之间的等价性。如果你使用 == 你会得到
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:
另一种选择是直接使用 Equals :
f (this.p.Equals.default(ProportionPoint))
回答by toddmo
I made an extension method that only works with structs:
我做了一个只适用于结构的扩展方法:
public static bool IsNull<T>(this T source) where T:struct
{
return source.Equals(default(T));
}
Calling convention:
调用约定:
if(myStruct.IsNull())
DoSomething();
I understand that it isn't really checking if it's null. However, if I gave it a more precise name, like IsEmptyor IsDefault, in six months I would forget it's there and upon seeing the list of methods available not pick it. It's not technically a null check; but conceptually it is.
我知道它并没有真正检查它是否是null. 然而,如果我给它一个更精确的名字,比如IsEmptyor IsDefault,我会在六个月内忘记它在那里,并且在看到可用方法列表时不选择它。从技术上讲,这不是空检查;但在概念上确实如此。
回答by PragmaOnce
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.)
(例如,具有该值的结构(0,0,0)可能是未修改的默认值,或者它可能将原点存储在 3D 空间中。)
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.
避免这种误报问题的另一种方法是向结构体添加另一个属性 - 例如 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;
}
}
回答by ParkurMaster
You can't check struct on null but you can check on default unitialized value like this:
您不能在 null 上检查结构,但可以像这样检查默认的未初始化值:
if (instanceOfYourStruct == default)

