- 題名: 型パラメータとType型の違い
- 日時: 2010/08/14 18:17:41
- ID: 27173
- この記事の返信元:
- (なし)
- この記事への返信:
- [27174] Re[1]: 型パラメータとType型の違い2010/08/14 18:48:57
- [27177] Re[1]: 型パラメータとType型の違い2010/08/14 19:08:58
- ツリーを表示
■No27173に返信(チョロQさんの記事)
> 型パラメータと、System.Type 型の違いとは何なのでしょうか?
どこで躓いているのかが今一つ把握できないのですが、
Dim a As Integer
Dim b As Type = GetType(Integer)
この場合の a と b の違いは分かりますか?
もしも型パラメータが(Of T) の場合は、これが
Dim a As T
Dim b As Type = GetType(T)
という事になりますし、引数が ByVal x As T であれば、
Dim c As T = x
Dim d As Type = x.GetType() 'ただし x IsNot Nothing
と書けます。ここまでは良いのでしょうか?
>> 'XMLファイルから読み込み、逆シリアル化する
>> Dim cls As SampleClass = CType(serializer.Deserialize(fs), _
>> SampleClass)
> ↑この SampleClass の部分を「 T 」とするとエラー。
それは、
Dim cls As T = CType(serializer.Deserialize(fs), T)
という事でしょうか? どのようなエラーでしたか?
> 引数の冗長化しているようで、どうもすっきりしません。
問題点が良く分かりませんが、型パラメータに付いていえば
Sub Method1(Of T)(ByVal x As T)
であれば、引数から型が判定できるため、呼び出し時の Of を省略できます。
一方、引数などから判定できない場合:たとえば
Function Method2(Of T)(ByVal x As Object) As T
の場合は、呼び出し時に Of で型パラメータを指定する必要があります。
ただし、これが「Class Class1(Of T)」内のメソッドであるならば、
T の型は Class1 が既に知っているため、Method2 メソッドの呼び出し時に
Of の指定を省略することができます。
> オブジェクトのXMLシリアライズ、逆シリアライズを行うメソッドを分けて作りました。
分けて作ったというのは、シリアライズ機能を SampleClass のメソッドにせず、
別クラスのメソッドとした…という意味でしょうか?
どのような実装なのか、具体的な部分が良く分かりませんでしたが、
とりあえず、型パラメータを使って書いてみました。
Public Class SampleClass
Public Number As Integer
Public Message As String
Public Overrides Function ToString() As String
Return String.Format("[{0}]{1}", Number, Message)
End Function
End Class
Class MainClass
Public Shared Function ToStream(Of T)(ByVal target As T) As System.IO.Stream
Dim serializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
ToStream = New System.IO.MemoryStream()
serializer.Serialize(ToStream, target)
ToStream.Seek(0, IO.SeekOrigin.Begin)
End Function
Public Shared Function FromStream(Of T)(ByVal target As System.IO.Stream) As T
Dim serializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
FromStream = CType(serializer.Deserialize(target), T)
End Function
Public Shared Sub Main()
Dim cls1 As New SampleClass()
cls1.Message = "テストです。"
cls1.Number = 123
Using stm As System.IO.MemoryStream = ToStream(cls1)
Dim cls2 As SampleClass = FromStream(Of SampleClass)(stm)
Console.WriteLine(cls1)
Console.WriteLine(cls2)
stm.Position = 0
Console.WriteLine(New System.IO.StreamReader(stm).ReadToEnd())
End Using
Console.ReadKey()
End Sub
End Class
分類:[.NET]
自作したジェネリックメソッドで(Of T)等として指定する型パラメータ T を
Type 型の値の代わりに使おうとするとエラーになってしまいます。
型パラメータと、System.Type 型の違いとは何なのでしょうか?
混乱してしまったきっかけは、自作クラスを作っている時です。オブジェクトのXMLシリアライズ、逆シリアライズを行うメソッドを分けて作りました。
シリアライズの方は、引数に obj as Object を渡し、その obj をシリアライズして書き出すメソッドが完成しました。逆シリアライズでは、obj を渡しても、この型が何なのか知ることができず、結局、オブジェクトの型も渡さなければなりませんでした。引数の冗長化しているようで、どうもすっきりしません。逆シリアライズのメソッドのみ、(Of T)のジェネリックメソッドになっているのも、ややこしいです。
また、逆シリアライズを行う際、一部のコードでは、型パラメータ T ではなく、Dim obj As new T とした後で、obj.GetType を代入しなければなりませんでした。
(以下、.NET TIPS のページ
http://dobon.net/vb/dotnet/file/xmlserializer.html
から引用)
> 'XMLファイルから読み込み、逆シリアル化する
> Dim cls As SampleClass = CType(serializer.Deserialize(fs), _
> SampleClass)
↑この SampleClass の部分を「 T 」とするとエラー。
Dim obj As new T として obj を作った後、「obj.GetType」を指定すると成功。
この違いは何なのでしょうか。