■92102 / inTopicNo.8) |
Re[5]: StructureでNothingかどうか判定する方法 |
□投稿者/ 魔界の仮面弁士 (2321回)-(2019/08/25(Sun) 23:35:24)
|
操作ミスって削除してしまったので再送。
■No92095 (る さん) に返信 > どのように使えば良いですか? Hongliang さんはあくまでも、必要な定義を示してくれているだけです。 それぞれの Function や Operator の中身を実装するのは、るさん御自身の役目ということで。
■No92097 (る さん) に返信 > としてもエラーとなりますが > どのようにしたら良いですか?
構造体 ddd に何も手を加えないのなら、 Dim ggg As ddd If ggg.Equals(CType(Nothing, ddd)) Then のようにすることで、初期値判定することができます。
しかし、Nothing を先の a 判定のために If ggg Is Nothing Then のように使いたいのであれば、 「Dim ggg As ddd」を「Dim ggg As ddd?」に変更するか、もしくは、 型 ddd を 構造体 からクラスに置き換える必要があります。
また、Nothing を先の b の意味で使い、 If ggg = Nothing Then としたい場合には、Hongliang さんが書かれていたように、 構造体に対して等価演算子をオーバーロードする必要があります。
つまり、下記の実装が必要になるという事です。
(1) 『Public Shared Operator =(l As ddd, r As ddd) As Boolean』を実装する。 (2) 『Public Shared Operator <>(l As ddd, r As ddd) As Boolean』を実装する。 (3) Object.Equals をオーバーライドする。『Public Overrides Function Equals(obj As Object) As Boolean』 (4) Object.GetHashCode をオーバーライドする。『Public Overrides Function GetHashCode() As Integer』
ここまでが最低限必要となるものです。(コンパイルを通すだけなら、1と2だけでも動きますが…) 可能ならばこれに加えて、IEquatable(Of ddd) インターフェイスも実装することが望ましいです。
Visual Studio 2017 以降をお使いであれば、構造体宣言の 「Structure ddd」と書かれた行のどこかにカーソルがある状態で (a) 左端の「豆電球」アイコンをクリックする (b) Alt + Enter を押す (c) Ctrl + . を押す のいずれかの操作を行ってみてください。
ポップアップメニューが表示されるので、そこから『Equals および GetHashCode を生成する...』を クリックした上で、その次のダイアログで『演算子を生成する』のチェックを入れて OK してみてください。 それだけで上記 4 つがすべて自動で実装されますので、手間もほとんどかかりません。 https://docs.microsoft.com/ja-jp/visualstudio/ide/reference/generate-equals-gethashcode-methods?view=vs-2017
※自動生成されるコードの内容は、ターゲットとなる .NET Framework バージョンによって異なっており、 より新しいバージョン向けの方が、よりスマートなコードとして生成されます。
VS2017 未満のバージョンをお使いの場合は、これらの実装を自ら実装する必要があります。 具体的にはこんな感じです。
Public Structure ddd ' 等価性判定のためのインターフェース。無くても動くけど、「不変性のある構造体」の場合は付与した方が望ましい。 'Implements IEquatable(Of ddd)
Public Property x As Integer Public Property y As Integer
'【今回の肝】「= 演算子」のオーバーロード Public Shared Operator =(l As ddd, r As ddd) As Boolean Return l.x = r.x AndAlso l.y = r.y ' 各メンバーが等しければ、同じ値と見なす End Operator
'【今回の肝】「<> 演算子」のオーバーロード Public Shared Operator <>(l As ddd, r As ddd) As Boolean Return Not (l = r) ' このように、= 演算子を Not 判定して書くことが多い End Operator
'【今回の肝】 Object.Equals(Object) をオーバーライド Public Overrides Function Equals(obj As Object) As Boolean ' 型が ddd であった場合は「= 演算子」で一致判定。違う型なら常に False。 Return TypeOf obj Is ddd AndAlso DirectCast(obj, ddd) = Me End Function
'【今回の肝】 Object.GetHashCode() をオーバーライド Public Overrides Function GetHashCode() As Integer Return x Xor y End Function
'' Equals(ddd) なオーバーロード メソッド 'Public Overloads Function Equals(other As ddd) As Boolean Implements IEquatable(Of ddd).Equals ' Return Me = other ' 実際の比較は、オーバーロードした = 演算子で行う 'End Function End Structure
|
|