DOBON.NETプログラミング道掲示板
(現在 過去ログ2 を表示中)

[ 最新記事及び返信フォームをトピックトップへ ]

■33500 / inTopicNo.1)  ダウンキャストの実装を簡潔に記述したい
  
□投稿者/ 山田太郎 一般人(1回)-(2016/11/11(Fri) 16:57:20)
  • アイコン環境/言語:[OS : Windows 7 / 言語 : Visual Basic .NET / .NET Framework : 4.5] 
    分類:[.NET] 

    【解決したい問題】
    
    PersonClassからEmployeeClassへのダウンキャストの実装を、
    できるだけ簡潔に記述したいと考えております。
    
    ダウンキャスト後にemployee.Nameとemployee.Ageに
    person.Nameとperson.Ageの値が入っている必要があります。
    
    以下のコードは
     employee = DirectCast(person, EmployeeClass)
    の場所でSystem.InvalidCastExceptionが発生します。
    
    
        Sub Main()
            Dim person As New PersonClass
            person.Name = "山田太郎"
            person.Age = 22
    
            Dim employee As New EmployeeClass
            employee = DirectCast(person, EmployeeClass)
            employee.EmployeeCode = "1234"
        End Sub
    
    
        Private Class PersonClass
            Property Name As String
            Property Age As Integer
        End Class
    
        Private Class EmployeeClass
            Inherits PersonClass
            Property EmployeeCode As String
        End Class
    
    【解決するために何をしたか】
    以下のようにコードを修正したところ、エラーは発生しなくなりました。
    しかしこの場合は、PersonClassのコンストラクタで
    全てのメンバーを設定しなくてはいけません。
    もっと簡潔に記述できる方法はないでしょうか?
    
    Sub Main()
            Dim person As New PersonClass
            person.Name = "山田太郎"
            person.Age = 22
    
            'Dim employee As New EmployeeClass
            'employee = DirectCast(person, EmployeeClass)
            'employee.EmployeeCode = "1234"
    
            Dim employee As New EmployeeClass(person)
            employee.EmployeeCode = "1234"
        End Sub
    
    
        Private Class PersonClass
            Property Name As String
            Property Age As Integer
    
            Sub New()
            End Sub
            Sub New(person As PersonClass)
                Me.Name = person.Name
                Me.Age = person.Age
            End Sub
        End Class
    
        Private Class EmployeeClass
            Inherits PersonClass
            Property EmployeeCode As String
    
            Sub New(person As PersonClass)
                MyBase.New(person)
            End Sub
        End Class

引用返信 削除キー/
■33501 / inTopicNo.2)  Re[1]: ダウンキャストの実装を簡潔に記述したい
□投稿者/ Azulean 大御所(478回)-(2016/11/12(Sat) 00:09:55)
  • アイコン
    2016/11/12(Sat) 00:10:47 編集(投稿者)
    
    一般にダウンキャストとは以下のことを指します。
    
    前提:A クラスを継承した B クラスがある
    ・B クラスとしてオブジェクトを生成し、A クラスとして変数や引数などに
     代入されている。
    ・そのままでは A クラスとしてしか扱えないので、実際の型である B クラスに
     キャストすることで、元の B クラスとして利用する。
    
    よって、ダウンキャストが成功するためには、元々、その型自身か、
    その型を継承した型として生成されていることが必要です。
    
    
    ■No33500に返信(山田太郎さんの記事)
    > 以下のコードは
    >  employee = DirectCast(person, EmployeeClass)
    > の場所でSystem.InvalidCastExceptionが発生します。
    
    今回、例示されていたコードは”ダウンキャストではありません。”
    person は元々、Person 型なので、EmployeeClass 型にキャストすることは
    できません。
    
    EmployeeClass 型を別途生成し、必要なメンバーをコピーするなど、実装が必要です。
    
    > しかしこの場合は、PersonClassのコンストラクタで
    > 全てのメンバーを設定しなくてはいけません。
    > もっと簡潔に記述できる方法はないでしょうか?
    
    近い実装量は必要です。
    EmployeeClass の方でプロパティに設定するコードを書けば、PersonClass 型に
    対しての追加は必要ないかもしれませんが。
    
    Private Class EmployeeClass
      Inherits PersonClass
      Property EmployeeCode As String
    
      Sub New(person As PersonClass)
        MyBase.New()
        Me.Name = person.Name
        Me.Age = person.Age
      End Sub
    End Class
    

引用返信 削除キー/
■33502 / inTopicNo.3)  Re[2]: ダウンキャストの実装を簡潔に記述したい
□投稿者/ Azulean 大御所(479回)-(2016/11/12(Sat) 00:29:51)
  • アイコン
    2016/11/12(Sat) 00:30:34 編集(投稿者)
    
    継承の関係が必須ではないのであれば、委譲・保有の関係を考えた方がよいかもしれません。
    
    Public Class EmployeeClass
        Property Person As PersonClass
        Property EmployeeCode As String
    
        Sub New(person As PersonClass)
            Me.Person = person
        End Sub
    End Class
    
    
    継承の関係が必要であり、メンバー変数が増えていくことに対する手間が大きいなら、
    内部構造体を持っておくのも良いかと思います。
    ただし、この場合、内部構造体に対するアクセサを書いているのでどっちが楽なのか?という点では微妙かもしれません。
    
    Public Structure PersonInfo
        Public Name As String
        Public Age As Integer
    End Structure
    
    Public Class PersonClass
        Protected _Info As PersonInfo
    
        Property Name As String
            Get
                Return _Info.Name
            End Get
            Set(value As String)
                _Info.Name = value
            End Set
        End Property
        Property Age As Integer
            Get
                Return _Info.Age
            End Get
            Set(value As Integer)
                _Info.Age = value
            End Set
        End Property
    
        Protected Sub CopyFrom(person As PersonClass)
            _Info = person._Info
        End Sub
    
    
    End Class
    
    Public Class EmployeeClass
        Inherits PersonClass
    
        Property EmployeeCode As String
    
        Sub New(person As PersonClass)
            CopyFrom(person)
        End Sub
    End Class
    
    
    ※どちらのケースも、ディープコピーとシャローコピーについて学んでおいた方が良いです。
    

引用返信 削除キー/
■33506 / inTopicNo.4)  Re[2]: ダウンキャストの実装を簡潔に記述したい
□投稿者/ 山田太郎 一般人(2回)-(2016/11/14(Mon) 12:11:44)
  • アイコンNo33501に返信(Azuleanさんの記事)
    > 今回、例示されていたコードは”ダウンキャストではありません。”

    ダウンキャストについて誤解しておりました。
    わかりやすい解説ありがとうございます。


    > 近い実装量は必要です。

    やはりそうなのですね。
    実際のプログラムではメンバ数が多いため、困っておりました。


    No33502に返信(Azuleanさんの記事)
    > 継承の関係が必須ではないのであれば、委譲・保有の関係を考えた方がよいかもしれません。

    PersonClassとEmployeeClassの関係は、継承を使わなければ実現できないと思い込んでおりました。
    この方法が私の理想に近いようです。
    EmployeeClass.Personのメンバがシャローコピーであることに気を付けて使用したいと思います。
    ありがとうございました。

解決み!
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

Mode/  Pass/


- Child Tree -