- ベストアンサー
VB.netでコレクションを変更させないようにするには
C#、VB.net(.net framework 2.0)で開発しております。 FamilyクラスのListフィールド_peopleには外部からの変更操作(Add、Remove等)を許可したくないのですが、 以下のようにReadOnlyのプロパティを設けても、代入操作はできないもののコレクション自体への変更は可能となってしまいます。 ※family.People.Add(mem) 等 IListやICollectionインターフェースをImplementして独自のコレクションを作り、 AddやRemoveメソッド内で例外を投げたりすることも考えたのですが、 そもそもコンパイルを通したくありません。 こういった場合、どのように実装するのが定石でしょうか? 宜しくお願い致します。 以下コード例 Public Class Family Dim _people As List(Of Member) Public ReadOnly Property People() As Member Get Return _people End Get End Property End Class
- i_110
- お礼率60% (28/46)
- Visual Basic
- 回答数2
- ありがとう数3
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
読み込み専用のリストが欲しいのですよね。 ・IList(Of T) が欲しいのであれば,List(Of T).AsReadOnly メソッド http://msdn.microsoft.com/ja-jp/library/e78dcd75.aspx ・IList が欲しいのであれば,ArrayList.ReadOnly メソッド http://msdn.microsoft.com/ja-jp/library/t304hsay.aspx あとは,ToArrayメソッドで配列化という手もありますが。 http://msdn.microsoft.com/ja-jp/library/x303t819.aspx
その他の回答 (1)
- moooove
- ベストアンサー率0% (0/1)
Public Class Family Private _people As List(Of Member) 'コンストラクタ Public Sub New (ByRef arg As List(Of Member)) _people = New List(Of Member)(arg) End Sub 'フィールド値を取得するメソッド Public Function get(ByVal index As Integer) As Member Return _people.item(index) End Function End Class 通常なら上記のようにgetメソッドのみを持つラッパークラスを作成するのが普通ですが、 インターフェースを継承したいというあたりを考えると IListやICollectionとしても扱いたい場面があるということでしょうか? _peopleがListクラスのインスタンスである以上、AddやRemoveメソッドに制限をかけることは不可能です。 おおもとのインスタンスに影響を与えたくないという意味なら、 私なら_peopleの参照するインスタンスのコピーを渡す方法を取ります。 すなわち、 Return New List(Of String)(_people) といったようにします。
お礼
ありがとうございます。 >IListやICollectionとしても扱いたい場面があるということでしょうか? その通りです。IEnumerableを実装するという手もあるのでしょうが… >私なら_peopleの参照するインスタンスのコピーを渡す方法を取ります。 そうですね。しかし、受け取ったリストへの変更操作ができてしまうので混乱のもとになり、 スマートで無い気がしていました。 ともあれ、ありがとうございました。大変参考になりました。
関連するQ&A
- assigning a value to structure's member accessed via collection
Class SampleA Private SampleAPoints As New System.Collections.Generic.List(Of System.Drawing.Point) Public ReadOnly Property Points As System.Collections.Generic.List(Of System.Drawing.Point) Get Return SampleAPoints End Get End Property End Class Class himajin100000 Shared Sub Main Dim Samp As New SampleA Samp.Points.Add(New System.Drawing.Point(80,80)) Samp.Points(0).X = 40 Samp.Points(0).Y = 40 End Sub End Class 'とかやってたら 'Expression is a value and cannot be target of an assignment 'といわれてしまいました。 '参考 'http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=295107 'どうやって切り抜けますか?
- ベストアンサー
- Visual Basic
- VB2008: 独自例外とは?
独自例外の確認ための質問をします。 独自例外の発生をキャッチして表示する術がわからなくて苦肉の策でエラートラップを利用。 しかし、こういう事であれば何も独自例外を設定する必要がありません。 と思ったり、「スルーだからテストに<0除算>を選んだのが悪いのか?」と考えたり。 ともかく、判っているのか判っていないのかが判らない状態に陥っています。 そういうことで、独自例外について少し教えて頂ければ幸いです。 ' ============================== ' クラスプログラミング; 演習2 ' ============================== Module theClass Sub Main() On Error GoTo Error_Main Dim T1 As New TEST1 Debug.Print(T1.MembersLengthAverage.ToString) Exit_Main: Exit Sub Error_Main: ErrorMsg(Err.Description & "(Main)") Resume Exit_Main End Sub End Module ' ================================================================== ' クラス TEST1 ' ================================================================== <Serializable()> Public Class TEST1 Private _MemberCount As Integer Private _Member1 As String Private _Member2 As String ReadOnly Property MembersLengthAverage() As Integer Get If _MemberCount <> 0 Then Return (_Member1.Length + _Member2.Length) \ _MemberCount Else Throw New System.Exception("TEST1: 除算エラーが発生しました。" ) End If End Get End Property Public Sub New() _Member1 = "" _Member2 = "" End Sub End Class
- ベストアンサー
- Visual Basic
- vb.netのプロパティの使い方について
こんにちわ! vb.netのプロパティの使い方がわからず困っています。 具体的にはTCPクライアント接続を行い、データ送信前に現在接続を行っているかチェックを行いたいです。 作ったのは↓ Public Class Form1 'ボタンを押したら Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim tcp_conect As New System.Net.Sockets.TcpClient 'ソケット作成 Dim net_stream As System.Net.Sockets.NetworkStream = Nothing 'ストリーム取得 Dim send_bytes As Byte() = {&HFF, &H0} '送信データ tcp_conect.Connect("192.168.1.1", "2000") 'ソケット接続 net_stream = tcp_conect.GetStream() 'ソケットストリーム取得 If tcp_conect.conected = True Then 'エラーが出てしまう。 net_stream.Write(send_bytes, 0, send_bytes.Length) 'データ送信 End If tcp_conect.Close() 'ソケット閉じる End Sub End Class 'プロパティ Public Class TcpClient Dim _conect_test As Boolean Public ReadOnly Property Connected As Boolean Get Stop Return _conect_test End Get End Property End Class これでテストをしたいのですが、プロパティが実行されません。 もしかしてプロパティの使い方がそもそも違うのかもしれないのですが、、、 アドバイスのほどよろしくお願いいたします。 ちなみに使用しているのは windows7 Visual Studio Express 2012です。
- 締切済み
- その他(インターネット・Webサービス)
- For Each文内でのコレクションの変更について
VB.Net/C# .NET Framework2.0で開発しております。 下記コード例のように、イテレータループ内(For Each文)でのコレクションの変更(要素の削除)ができないため、苦肉の策として下のように削除する予定のものを格納するバッファ(removeList)に一度登録し、その後もう一度ループをまわして実際に削除する、というコードを書いておりますが、分量も多くなり、一時変数なども出てくるため、あまりよいコードとは言えないと思います。 コレクションから特定の条件を満たした要素を削除するための、もうすこしスマートな書き方はないものでしょうか? 宜しくお願いいたします。 Dim removeList as new List(Of TestClass) For Each e as TestClass in targetList If e.IsDummy Then '直接targetList.Remove(o) とはできない removeList.Add(o) End If End For For Each e as TestClass in removeList targetList.Remove(e) End For
- ベストアンサー
- Visual Basic
- VBSでのコレクション
教えてください。 VBのコレクション配列はVBSにはあるのでしょうか? クラスオブジェクトをコレクション配列に入れたいのですが.... 例: Class myclass : : End Class Sub Main() dim col as Collection dim mycl mycl = new myclass col = new myClass for i =0 to max myclass.xxx = xxxx col.add i mycl next End Sub 以上簡単ですが、myclをコレクション配列に格納したいのですが、
- ベストアンサー
- Visual Basic
- VB.NETで出来てC#で出来ない???
VB.NETでは出来るのにC#で同じようにするやり方がわからなくて困っています。 VSのバージョンは2008です。 やりたいことは 『param.Item("AAA") = "111"』 このように書けるクラスを作りたいのですが、 VBで出来てC#では出来ないのでしょうか? イメージとしてはプロパティにメソッドをくっつけたようなクラス? C#ではこのように書くとエラーになります。 どのようにしたらいいでしょうか? public string Item(string Key) { set { _param[Key] = value; } } VB Dim param As New Param() param.Item("AAA") = "111" ----Paramクラス---- Imports System.Text Public Class Param Private _Hash As New Hashtable Default Public Property Item(ByVal Key As String) As String Get Return _Hash(Key) End Get Set(ByVal value As String) _Hash(Key) = value End Set End Property End Class ---------
- ベストアンサー
- その他(プログラミング・開発)
- プロパティを通さなければアクセスできない変数を設定したい(VB2005)
下記はメンバ変数とプロパティのコードです。 -------------------------------------- 'メンバ変数 Private _hoge As Integer = 1 'プロパティ Private ReadOnly Property phoge() Get Return _hoge End Get End Property -------------------------------------- 上記の構造だと、同じクラス内であれば、下記のようにメンバ変数へプロパティを通さずアクセスが可能です。 Private Sub aaa() MessageBox.Show(_hoge) ' 1 と表示される(ここでエラーを出したい) End Sub 質問内容は、変数_hogeに対してアクセスするには、(同じクラス内からのアクセスであっても)プロパティを通さなければならない形にしたい、というものです。 つまり、下記のような形でないとエラーが発生するようにしたいと考えています。 Private Sub aaa() Dim foo As Integer = phoge() MessageBox.Show(foo) End Sub どうぞよろしくお願い致します。
- ベストアンサー
- Visual Basic
- VB.NETで変数の宣言が上手くできません
VB.NETで変数の宣言が上手くできません プロパティを使用し、変数の内容を一括保存しようと考えています その為に以下のようなコードを書いたのですが他のフォームから宣言されていないとなってしまいます 修正点を教えて頂けると嬉しいです Setting.vb Pubic class Settings Public dbdirectry As String Public flistpass As String Public Property flist () As String Get Return flistpass End Get Set (Byval Value As String) flistpass = Value End Set End Property もう一つflist () をdbdic ()に flistpassをdbdirectryにしたもの End Class この変数2つに他のフォームMainForm1.vbとDefaultSetting.vbなどからflistpass = Newflistpassなどと記述するとアクセス出来ず宣言していない扱いになります Publicでの宣言で大丈夫だと思ったのですが間違えているのでしょうか?
- ベストアンサー
- Visual Basic
- VB.NET getとsetの概念がわかりません。
GetとSetがどういう働き・意味をもっているのか理解できていません。 たとえばSpecialTextBoxというクラスがあったとします。 *************************************************************** Imports System.Web.UI.MobileControls Partial Class SpecialTextBox Inherits System.Web.UI.MobileControls.MobileUserControl Public Property Item() As SelectionList Get Return Me.CheckBox End Get Private Set(ByVal value As SelectionList) Me.CheckBox = value End Set End Property End Class **************************************************************** ここでのGet Setはどういう動き・働きをしているんでしょうか? わかる方がいたらご助言お願いいたします。 (サンプルソースなどがあれば理解しやすいかもしれません。。)
- ベストアンサー
- Visual Basic
- VB6構造体をVB2008クラスで行う場合
何方かの質問「VB6構造体をVB2008クラスで行う場合」 の回答プログラムにて参考とさせて頂きましたが 申し訳ありません、初心者しにて・・・・・教えてください。 値を「登録、参照部分」のクラス(抜粋) Public Class Program Public Shared Sub Main() (省略) End Sub End Class 上記部分なのですが (1)Sharedを使用する訳はなんでしょうか?(省いても問題ありませんか?) (2)登録、参照部分のクラスPublic Shared Sub Main()を「登録のメソッド」と「参照のメソッド」に 分けたいのですがどうしてもうまくいきません。 何方か御教授願えないでしょうか? よろしくお願いします。 「以下何方かの質問の回答プログラム」 ■クラス+コレクションクラス Public Class Group Public MainID As Integer Public SubID As Integer Public Value1 As Integer Public Value2 As Integer End Class Public Class GroupCollection : Inherits System.Collections.Generic.Dictionary(Of Integer, Group) Public Shadows Sub Add(ByVal Item As Group) MyBase.Add(Item.SubID, Item) End Sub End Class Public Class Program Public Shared Sub Main() Dim DataDict As New GroupCollection Dim NewGroup As New Group NewGroup.MainID = 1 NewGroup.SubID = 101 NewGroup.Value1 = 123 NewGroup.Value2 = 234 DataDict.Add(NewGroup) Console.WriteLine(DataDict.Item(101).Value2) ' 出力 234 End Sub End Class
- ベストアンサー
- Visual Basic
お礼
ありがとうございます。 >AsReadOnly メソッド 素晴らしいです。まさにこれを求めていました。 本当にありがとうございました。 しかしこういったものは教えて頂かなかったら一生気付かない気がしますね…いや、単に私の調査不足でしょうか。 ともあれ、大変感謝しております。ありがとうございました。