- 題名: 型パラメータと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」を指定すると成功。
この違いは何なのでしょうか。