web-dev-qa-db-ja.com

構造体がインスタンス化されているかどうかを確認するにはどうすればよいですか?

(この質問の目的のために)ビルトインPointタイプをほぼ模倣する構造体があります。

使用する前に、インスタンス化されていることを確認する必要があります。 Pointの場合、これを行うことができました。

if (this.p == null)

しかし、現在では次のエラーが生成されます。

演算子 '=='は、タイプ 'ProportionPoint'および '<null>'のオペランドには適用できません

構造体をヌルと比較するにはどうすればよいですか?インスタンス化を確認する別の方法はありますか?

25
Tom Wright

structは値の型です-nullになることはありません。

default(ProportionPoint)に対して確認できます。これは、構造体のデフォルト値(たとえば、ゼロ)です。ただし、ポイントについては、デフォルト値-Origin-も「有効な」値である可能性があります。

代わりに、Nullable<ProportionPoint>

33
Rawling

構造体は値型であり、参照型に反してnullになることはありません。デフォルト値に対してチェックできます:

if (this.p.Equals(default(ProportionPoint)))
15
Darin Dimitrov

pは構造体であるため、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))
4
Technovation

Nullableを使用します:

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

または

if (!p1.HasValue) ...
2

構造体をnullにすることはできません値の型、参照型ではありません。デフォルト値を使用してプロパティをチェックする必要があります。何かのようなもの:

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

構造体がnullになることはないため、nullと比較することはできません。そして、構造体は常に初期化されます-ユーザーでない場合、コンパイラーはデフォルト値を使用します。

2
SomebodyYouKnow

参照型の変数または値とは異なり、 参照 そのタイプのゼロまたは1つのインスタンス、構造体変数または値  構造体インスタンス。 {Point myPoint; ...}で始まるコードブロックがあり、そのブロック内でMyPoint(ブロック内にyield returnがある場合、またはラムダまたは匿名メソッドは囲みブロックの変数を使用します)、Pointのインスタンスは、実行がブロックに入る前に存在し、実行がブロックを離れた後はいつでも存在しなくなる可能性があります。構造体型変数を使用できるコンテキストでは、構造体が存在します。

すべての構造タイプが何もしないデフォルトコンストラクターを持っていると見なされる理由は、構造タイプが暗黙的に存在するためです。 Point[] myPoints = new Point[100];のようなステートメントを実行すると、100個のPoint構造体のゼロで埋められた配列が作成されます。その過程で、100ゼロで埋められたPointインスタンスが即座に存在します。 C++では、型にコンストラクターがある場合、その型の配列を作成すると、コードがしばらくの間配列にアクセスする前に、配列のすべての要素でコンストラクターが順番に呼び出されます。要素の構築中に例外がスローされると、コンパイラー生成コードは、配列自体が蒸発する前に正常に作成されたすべての要素で決定論的なデストラクタを実行します。これは非常に強力な機能ですが、.net内に含めると、フレームワークが大幅に複雑になります。

1
supercat

構造体でのみ機能する拡張メソッドを作成しました:

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

呼び出し規約:

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

nullかどうかを実際にチェックしていないことを理解しています。ただし、IsEmptyIsDefaultなどのより正確な名前を付けた場合、6か月後にはその名前が存在することを忘れてしまい、使用可能なメソッドのリストを見てもそれを選択しないでください。技術的にはnullチェックではありません。しかし、概念的にはそうです。

0
toddmo