型の比較について教えて下さい。 への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 るきお  (社会人)
投稿日時
2021/6/21 21:10:03
何か説明されていないこだわりを秘めているように感じますが、
ひとまず、7 は obj が List(Of T)自身かそれを継承したものであるかを判定すればよいのですよね?
次のプログラムでどうでしょうか?
8 は obj が List(Of T)自身かそれを継承したものであり、かつ、T が ClassA自身かそれを継承したものであるという判定すればよいのですよね?
多分、私が紹介したプログラムでできることはわかっているけど、何かこだわっている制約があって、その制約を前提にどう実現するかということを気にされているのかなと感じました。
最近はこの手のプログラムはあまりはやっておらず、インターフェースや拡張メソッドを活用する方向性のように思います。
特にこのようなクラスの静的な定義を解析するプログラムは拡張メソッドに対応できませんから、本当に練習とか力試しの用途になるのではないかと思います。
何かの静的コード解析やメトリックで役に立つかどうか…。よろしければ、たこさんがこのようなプログラムに関心を持っている理由を教えてください。
ひとまず、7 は obj が List(Of T)自身かそれを継承したものであるかを判定すればよいのですよね?
次のプログラムでどうでしょうか?
Dim obj As Object = New SubListA(Of SubClassA)
Dim baseType = obj.GetType
While baseType.FullName <> "System.Object"
Dim name As String = baseType.FullName
If name.StartsWith("System.Collections.Generic.List`") Then
MsgBox("7,objは、List(Of) と一致")
End If
baseType = baseType.BaseType
End While
8 は obj が List(Of T)自身かそれを継承したものであり、かつ、T が ClassA自身かそれを継承したものであるという判定すればよいのですよね?
Dim obj As Object = New SubListA(Of SubClassA)
Dim baseType = obj.GetType
While baseType.FullName <> "System.Object"
Dim name As String = baseType.FullName
If name.StartsWith("System.Collections.Generic.List`") Then
Dim argType = baseType.GetGenericArguments(0)
While argType.FullName <> "System.Object"
Dim argTypeName = argType.FullName
If argTypeName = "WindowsApp1.Form1+ClassA" Then
MsgBox("8,objは、ジェネリック(Of ClassA) と一致")
End If
argType = argType.BaseType
End While
Exit While
End If
baseType = baseType.BaseType
End While
多分、私が紹介したプログラムでできることはわかっているけど、何かこだわっている制約があって、その制約を前提にどう実現するかということを気にされているのかなと感じました。
最近はこの手のプログラムはあまりはやっておらず、インターフェースや拡張メソッドを活用する方向性のように思います。
特にこのようなクラスの静的な定義を解析するプログラムは拡張メソッドに対応できませんから、本当に練習とか力試しの用途になるのではないかと思います。
何かの静的コード解析やメトリックで役に立つかどうか…。よろしければ、たこさんがこのようなプログラムに関心を持っている理由を教えてください。
投稿者 たこ  (その他)
投稿日時
2021/6/21 05:51:12
稚拙な質問なのですが、以前にも一度ここで教えて頂いたことがありましたので、質問失礼します。
Visual Studio2017/.NET Framework4.6.1/VBのWindowsFormアプリケーションです。
型の比較について教えて下さい。
ある変数「obj」が特定の型であるかどうかを判別する際、TypeOf や GetType を使うと思います。
配列や Generic のとき、どうすればいいのか分からず、調べたのですが、
継承されている場合の比較のやり方が分かりません。
例えば、
List(Of T) を継承した SubListA(Of T) の、
T の比較はできたのですが、SubListA(Of) であることの比較が、分かりません。
説明が下手かと思いますので、コードの7番目の所です。
9番目と10番目の部分もどう書けば良いのかさっぱりです。
またこちらはついでですが、GetType (Type型)による比較をする際(コードの3番目の所)
・Equalsメソッド
・Is 演算子
・= 演算子
Type型の比較おいて、この3種類はどれも同じものと思って良いのでしょうか。
またもしくは、一般的には、どういう理由でどれを使いますか?
教えてくださる方居ましたら、ご教示ください。
Visual Studio2017/.NET Framework4.6.1/VBのWindowsFormアプリケーションです。
型の比較について教えて下さい。
ある変数「obj」が特定の型であるかどうかを判別する際、TypeOf や GetType を使うと思います。
配列や Generic のとき、どうすればいいのか分からず、調べたのですが、
継承されている場合の比較のやり方が分かりません。
例えば、
List(Of T) を継承した SubListA(Of T) の、
T の比較はできたのですが、SubListA(Of) であることの比較が、分かりません。
説明が下手かと思いますので、コードの7番目の所です。
9番目と10番目の部分もどう書けば良いのかさっぱりです。
またこちらはついでですが、GetType (Type型)による比較をする際(コードの3番目の所)
・Equalsメソッド
・Is 演算子
・= 演算子
Type型の比較おいて、この3種類はどれも同じものと思って良いのでしょうか。
またもしくは、一般的には、どういう理由でどれを使いますか?
教えてくださる方居ましたら、ご教示ください。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim ss As New System.Text.StringBuilder
Dim obj As Object, t As Type
obj = New SubClassA
t = obj.GetType
If TypeOf obj Is ClassA Then
ss.AppendLine("1,基底クラスを含む、型の一致")
End If
If GetType(ClassA).IsAssignableFrom(t) Then
ss.AppendLine("2,基底クラスを含む、型の一致")
End If
If GetType(SubClassA) = t Then
ss.AppendLine("3,基底クラスを含まない、型の一致")
End If
obj = New SubClassA() {}
t = obj.GetType
If t.IsArray AndAlso GetType(ClassA).IsAssignableFrom(t.GetElementType) Then
ss.AppendLine("4,objは、配列 ClassA() と一致")
End If
obj = New List(Of SubClassA)
t = obj.GetType
If t.IsGenericType AndAlso
GetType(List(Of)).IsAssignableFrom(t.GetGenericTypeDefinition) Then
ss.AppendLine("5,objは、List(Of) と一致")
End If
If t.IsGenericType AndAlso
t.GenericTypeArguments.Count = 1 AndAlso
GetType(ClassA).IsAssignableFrom(t.GenericTypeArguments(0)) Then
ss.AppendLine("6,objは、ジェネリック(Of ClassA) と一致")
End If
obj = New SubListA(Of SubClassA)
t = obj.GetType
If t.IsGenericType AndAlso
GetType(List(Of)).IsAssignableFrom(t.GetGenericTypeDefinition) Then '一致してくれない
ss.AppendLine("7,objは、List(Of) と一致")
End If
If t.IsGenericType AndAlso
t.GenericTypeArguments.Count = 1 AndAlso
GetType(ClassA).IsAssignableFrom(t.GenericTypeArguments(0)) Then
ss.AppendLine("8,objは、ジェネリック(Of ClassA) と一致")
End If
obj = New SubListB
t = obj.GetType
If t.IsGenericType AndAlso
GetType(List(Of)).IsAssignableFrom(t.GetGenericTypeDefinition) Then '書き方がさっぱり分かりません
ss.AppendLine("9,objは、List(Of) と一致")
End If
If t.IsGenericType AndAlso
t.GenericTypeArguments.Count = 1 AndAlso
GetType(ClassA).IsAssignableFrom(t.GenericTypeArguments(0)) Then '書き方がさっぱり分かりません
ss.AppendLine("10,objは、ジェネリック(Of ClassA) と一致")
End If
MsgBox(ss.ToString)
End Sub
Private Class ClassA
End Class
Private Class SubClassA : Inherits ClassA
End Class
Private Class SubListA(Of T) : Inherits List(Of T)
End Class
Private Class SubListB : Inherits List(Of SubClassA)
End Class
すみません、仕事でも何でも無くただの趣味で、制約も何も有りません・・・。
偏った知識で奇妙なコードで申し訳ないです・・・。
なるほどBaseTypeを再起すれば良かったのですね。
7,9,10、分からなかった部分、綺麗に判定できました。
感謝です。
前述のように制約なんてものは有りませんが、
経緯は、PropertyGrid で動的なデフォルト値を作りたくて・・・です。
インターフェースや拡張メソッドも使っていますが、
確かに今考えると、Object型を使う必要はなかったかもしれません。
ですが、私の場合本当に趣味で書いてるだけなので、
分からなかったことが書けるようになって満足です。
また機会ありましたら、掲示板利用させてもらえると幸いです。