C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: 親クラスをどうやってプロパティで参照するか


(過去ログ 53 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■29246 / inTopicNo.1)  親クラスをどうやってプロパティで参照するか
  
□投稿者/ 初心者 (194回)-(2008/12/06(Sat) 06:15:33)

分類:[.NET 全般] 

いつも参考にしています。
質問です。

ツリーノードのような階層的なクラスを作りたいのですが
 @親を取得するプロパティの構築方法
 A下層のノードを取得するプロパティの構築方法
@Aについて下記のコードで一応期待している動作はするのですが、
netでの独学なので、不安なのですが
このような記述は一般的な表現方法なのでしょうか
また、もっとスマートな方法はないのでしょうか

Public Class TestNode
Public 親 As TestNode
Dim Nodes As List(Of TestNode)
Public Sub add(ByVal value As TestNode)
Nodes.Add(value)
value.set親(Me)
End Sub
Public Sub set親(ByVal value As TestNode)
Me.親 = value
End Sub
Public ReadOnly Property Parent()
Get
Return 親
End Get
End Property
End Class
引用返信 編集キー/
■29247 / inTopicNo.2)  Re[1]: 親クラスをどうやってプロパティで参照するか
□投稿者/ .SHO (311回)-(2008/12/06(Sat) 10:55:26)
VBってParentプロパティ使えないのですか?
引用返信 編集キー/
■29250 / inTopicNo.3)  Re[1]: 親クラスをどうやってプロパティで参照するか
□投稿者/ よねKEN (218回)-(2008/12/06(Sat) 11:29:38)
2008/12/06(Sat) 11:31:01 編集(投稿者)
前置きですが、Parentプロパティを持たなくても、必要なことが実現できるのであれば、
できれば持たない方がいいですよ。Parentプロパティを整合性を持って管理されるように
実装するのって結構大変なんで。

> netでの独学なので、不安なのですが
> このような記述は一般的な表現方法なのでしょうか

方向性としては間違っていないと思います。
細かいところまで見ると修正すべき点はいろいろありますので、ツッコミ入れますね。

> Public Class TestNode
>     Public 親 As TestNode

せっかくプロパティを用意しているのでPublicではなくPrivate辺りが妥当ではないでしょうか。

>     Dim Nodes As List(Of TestNode)

Dimキーワードよりもこの場合であればPrivateキーワードを使う方がいいと思います。
クラスの変数としてDimを指定した場合は意味としてはPrivateですので動作上は問題ありませんが、
Privateだと明示する表現の方が好ましいです。

>     Public Sub add(ByVal value As TestNode)
>         Nodes.Add(value)
>         value.set親(Me)
>     End Sub

addではなくAddメソッドとしてください。クラスライブラリのメソッドもそうなってますよね。

また、ここではAddメソッドを実装していますが、
Removeメソッド/Insertメソッド/NodesをClearするようなメソッドが必要になった場合も
親の設定が必要になりますので注意が必要です。

>     Public Sub set親(ByVal value As TestNode)
>         Me.親 = value
>     End Sub

親の設定は外部から勝手に変更されると困るのでPublicではなくPrivateにした方がよいでしょう。

>     Public ReadOnly Property Parent()
>         Get
>             Return 親
>         End Get
>     End Property
> End Class

Parentプロパティの戻り値型の指定が漏れています。As TestNodeを付加しましょう。

また、ジェネリックスが使えるバージョンのVBなら、
プロパティのGetとSetでそれぞれ別のスコープを用意することができます。
set親メソッドを廃止して、以下のようにすれば外部からはParentプロパティは参照のみ、
クラス内部ではセットも可能というふうに記述できます。

     Public Property Parent() As TestNode
        Get
             Return 親
        End Get
        Private Set(ByVal value As TestNode)
            親= value
        End Set
     End Property

引用返信 編集キー/
■29252 / inTopicNo.4)  Re[1]: 親クラスをどうやってプロパティで参照するか
□投稿者/ よねKEN (219回)-(2008/12/06(Sat) 11:37:57)
2008/12/06(Sat) 11:40:45 編集(投稿者)
> また、もっとスマートな方法はないのでしょうか

スマートかどうかはわかりませんが、TestNodeとTestNode専用のコレクションを用意する方法にすると
TreeNodeとほぼ同じような使い方をすることができますので、使う人は使いやすいかもしれませんね。

私が書くなら・・・というサンプルです。(あくまでサンプルなので鵜呑みにしないでね)
※以下のコードは、Parentの制御は手抜きをしてAdd/Insert/Remove/RemoveAtしかやってません。

Imports System.Collections
Imports System.Collections.Generic

Public Class TestNode
    Private _parent As TestNode
    Private _nodes As TestNodeCollection
    Public Sub New()
        _nodes = New TestNodeCollection(Me)
    End Sub
    Public ReadOnly Property Nodes() As TestNodeCollection
        Get
            Return _nodes
        End Get
    End Property
    Public Property Parent() As TestNode
        Get
            Return _parent
        End Get
        Friend Set(ByVal value As TestNode)
            _parent = value
        End Set
    End Property
End Class

Public Class TestNodeCollection
    Implements IList(Of TestNode)

    Private _nodes As List(Of TestNode)
    Private _parent As TestNode

    Public Sub New(ByVal parent As TestNode)
        _parent = parent
        _nodes = New List(Of TestNode)
    End Sub

    Public Sub Add(ByVal item As TestNode) Implements ICollection(Of TestNode).Add
        item.Parent = _parent
        _nodes.Add(item)
    End Sub

    Public Sub Clear() Implements ICollection(Of TestNode).Clear
        _nodes.Clear()
    End Sub

    Public Function Contains(ByVal item As TestNode) As Boolean _
        Implements ICollection(Of TestNode).Contains
        _nodes.Contains(item)
    End Function

    Public Sub CopyTo(ByVal array() As TestNode, ByVal arrayIndex As Integer) _
        Implements ICollection(Of TestNode).CopyTo
        _nodes.CopyTo(array, arrayIndex)
    End Sub

    Public ReadOnly Property Count() As Integer Implements ICollection(Of TestNode).Count
        Get
            Return _nodes.Count
        End Get
    End Property

    Public ReadOnly Property IsReadOnly() As Boolean _
        Implements ICollection(Of TestNode).IsReadOnly
        Get
            Return False
        End Get
    End Property

    Public Function Remove(ByVal item As TestNode) As Boolean _
        Implements ICollection(Of TestNode).Remove
        item.Parent = Nothing
        Return _nodes.Remove(item)
    End Function

    Public Function GetEnumerator() As IEnumerator(Of TestNode) _
        Implements IEnumerable(Of TestNode).GetEnumerator
        Return _nodes.GetEnumerator()
    End Function

    Public Function IndexOf(ByVal item As TestNode) As Integer Implements IList(Of TestNode).IndexOf
        Return _nodes.IndexOf(item)
    End Function

    Public Sub Insert(ByVal index As Integer, ByVal item As TestNode) Implements IList(Of TestNode).Insert
        item.Parent = _parent
        _nodes.Insert(index, item)
    End Sub

    Default Public Property Item(ByVal index As Integer) As TestNode Implements IList(Of TestNode).Item
        Get
            Return _nodes.Item(index)
        End Get
        Set(ByVal value As TestNode)
            value.Parent = _parent
            _nodes.Item(index) = value
        End Set
    End Property

    Public Sub RemoveAt(ByVal index As Integer) Implements IList(Of TestNode).RemoveAt
        _nodes(index).Parent = Nothing
        _nodes.RemoveAt(index)
    End Sub

    Private Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
        Return _nodes.GetEnumerator()
    End Function
End Class

引用返信 編集キー/
■29276 / inTopicNo.5)  Re[2]: 親クラスをどうやってプロパティで参照するか
□投稿者/ たくボン (97回)-(2008/12/06(Sat) 21:30:20)
2008/12/06(Sat) 21:30:51 編集(投稿者)
No29252 (よねKEN さん) に返信
> 2008/12/06(Sat) 11:40:45 編集(投稿者)
> > また、もっとスマートな方法はないのでしょうか

俺もよねKENさんと同じかな。
個々のTreeNodeクラスに親ノードを持たせるのは冗長ですからね。

ソース載せようかと思ったけどよねKENさんが提示してくれたし、これがほぼ正解に近いと思います。
Grnericは使いやすいから便利なんだけど、決められた動作しか提供してくれないのでどうしても細かい制御が必要なら継承ですね。
俺はGeneric出る前に作ったツールを使って生成してるから、■No26127みたいな感じで使ってるんだけど、インターフェース+Genericどっちが便利だろ?
せっかくGenericも使えることだし書き直してみるかな。

# 個人的には再帰の処理をよく使うので、FirstNode, PrevNode, NextNode, LastNodeの相対関係なんかもAddの時にしてます。


引用返信 編集キー/
■29453 / inTopicNo.6)  Re[3]: 親クラスをどうやってプロパティで参照するか
□投稿者/ 初心者 (199回)-(2008/12/09(Tue) 23:07:07)
レスが遅くなり、大変申し訳ありません
大変貴重なコードをありがとうございます
コードを参考にさせていただき、修正したいと思います
コードを自分なりに解釈して、理解できてから解決とさせていただきたいちお
思います
かっこいいコードを教えていただき
本当にありがとうございました

引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -