- PR -

コンストラクタとShared

投稿者投稿内容
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-06-18 18:49
引用:

にゃごさんの書き込み (2006-06-18 17:34) より:

「普通のコンストラクタ」「静的コンストラクタ」「タイプイニシャラザ」というあたりから、理解が怪しくなってます。上記のようなことを可能にするには、どういった手段が適当なのでしょうか?


本来は、

コード:

    Private Shared m_id As Long 

    Public Shared ReadOnly Property ID() As Long
        Get
            Return m_id
        End Get
    End Property

    Private Shared m_name As String 

    Public Shared ReadOnly Property Name() As String
        Get
            Return m_name
        End Get
    End Property

    Shared Sub New()
        m_id   = 10
        m_name = "Hoge"
    End Sub


とか、

コード:

    Public Shared ReadOnly ID   As Long   = 15
    Public Shared ReadOnly Name As String = "Hoge"


で、良いのですが、

引用:

”12345”の箇所は利用者に設定してもらいたいのです・・・。
ReadOnlyだから、無理っぽいような。


共有メンバである以上、それは無茶な話です。
「タイプ イニシャライザ」に引数は指定できません。

共有メンバでないのであれば、コンストラクタで引数を渡すことができます。
使用者がコンストラクタで値を設定し、メンバ自体は、ReadOnly という形にできます。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-06-18 19:12
引用:

にゃごさんの書き込み (2006-06-18 17:34) より:

やりたいことのイメージは、2つめでかるあ様がおっしゃっていることがズバリです。


僕もかるあさんの2つめの意見と同じだったのですが、その後の投稿を見て、どうして静的コンストラクタ?、って思ったらタイトルがそうなってたんですねw

引用:

にゃごさんの書き込み (2006-06-18 17:34) より:

(あ、ちなみにWindowsプログラムです。ASP.netではありません(^^


今回のお話はオブジェクト指向ちっくな話なので、これは気にしなくてもOKかと。

サンプルコード惜しいっ。
コード:
Public Class Test 
    Private m_id As Long 
    Private m_name As String 

    Public Sub New(ByVal userId As Long, ByVal userName As String) 
        m_id = userId 
        m_name = userName 
    End Sub 

    Public ReadOnly Property UserId() As Long 
    '読み取り専用なので、Setはなし 
        Get 
            Return m_id 
        End Get 
    End Property 

    Public ReadOnly Property UserName() As String 
    '読み取り専用なので、Setはなし 
        Get 
            Return m_name 
        End Get 
    End Property 
End Class 


このコードだとオブジェクトを生成して、生成時に初期化します。

#Shared 取っただけかな?
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2006-06-18 19:47
項目が複数なら、IdやNameといった個々のデータはインスタンスメンバにしておいて、
Sharedなプロパティあたりにインスタンスを設定したほうが後々いいかもしれません。

ユーザが初期化するなら、初期化メソッドかプロパティのセッターで
初期化できるようにすればいいでしょう。
※初期化後は変更できないようにしたいとかだとなんらかチェックなりが必要ですが

別に個々のデータをバラで共有メンバに持ってもいいんですが、インスタンスで
ひとまとめに持つようにしたほうが、後々扱いやすい可能性があります。
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2006-06-18 21:18
NAL-6295です。

本筋とは関係なくて、申し訳ありませんが
引用:

タイプイニシャライザ
静的コンストラクタ


を「マイクロソフト公式解説書 プログラミングMicrosoft .NET Framework」
の影響で
「タイプコンストラクタ」
と呼んでました。

いろんな呼び方があるなぁ。と思ったまでです。
にゃご
会議室デビュー日: 2006/06/17
投稿数: 10
投稿日時: 2006-06-19 10:16
引用:

囚人さんの書き込み (2006-06-18 17:43) より:
コード:
Private Shared m_id As Long 
Private Shared m_name As String 


Shared にする必要はありますか?
Shared にしないで、普通に読み取り専用ならば簡単だと思いますよ。
「ID」や「名前」といったものは共有でないないと思うのですが…。(まぁ一概には言えませんが)





このクラスライブラリを参照している複数のプロジェクトから、値を参照したかったためにSharedにしてみました。

 前提:クラスライブラリはHoge、クラス名はTest。
    Project1,2,3はクラスライブラリHogeをプロジェクト参照している。

 1.Project1で、値を設定。
 2.Project2またはProject3から、Project1で設定した値をとる。

プロジェクトをまたいだ、グローバル変数みたいな使い方でしょうか。ただ、”グローバル変数はなるべく使わないほうがよい”とあちこちで見たので、クラスでどうにかなるものかな?と・・・。
にゃご
会議室デビュー日: 2006/06/17
投稿数: 10
投稿日時: 2006-06-19 10:35
引用:

じゃんぬねっとさんの書き込み (2006-06-18 18:49) より:
共有メンバである以上、それは無茶な話です。
「タイプ イニシャライザ」に引数は指定できません。

共有メンバでないのであれば、コンストラクタで引数を渡すことができます。
使用者がコンストラクタで値を設定し、メンバ自体は、ReadOnly という形にできます。




これ(↓)ってありでしょうか?

まず実現したいと思ったのは次のようなことです。

・複数プロジェクトで同じ値を参照したい。
・Testクラスはすべてのプロジェクトでプロジェクト参照している。
・値はプロジェクト1でだけ設定される。
・他のプロジェクトはプロジェクト1で設定された値を参照するだけ。
(前のトピックでも書きましたが、みればみるほどグローバル変数っぽいな・・・)

で、いろいろしつこくコードを試してみると、下記のようなコードで、やりたいことが実現できている(ように見える)のですが・・・。これってありでしょうか?

クラスライブラリ:HOGE
コード:

Public Class Test
Private Shared m_id As Long
Private Shared m_name As String

Public Sub New(ByVal userId As Long, ByVal userName As String)
m_id = userId
m_name = userName
End Sub

Public Shared ReadOnly Property Id() As Long
Get
Return m_id
End Get
End Property

Public Shared ReadOnly Property UserName() As String
Get
Return m_name
End Get
End Property
End Class



値を設定するプロジェクト
コード:

Dim userId As Integer
Dim userName As String

userId = InputBox("IDを指定してください", "UserId")
userName = InputBox("名前を入れてください", "UserName")

Dim hogehoge As New Hoge.Test(userId, userName)

MessageBox.Show(Hoge.Test.Id)
MessageBox.Show(Hoge.Test.UserName)

hogehoge = Nothing



参照している別のプロジェクト
コード:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

LabelId.Text = Hoge.Test.Id.ToString
LabelUserName.Text = Hoge.Test.UserName

End Sub



※まずいのかな?


[ メッセージ編集済み 編集者: にゃご 編集日時 2006-06-19 10:41 ]

[ メッセージ編集済み 編集者: にゃご 編集日時 2006-06-19 10:44 ]
たつ64
会議室デビュー日: 2005/08/02
投稿数: 16
お住まい・勤務地: 天下の台所?
投稿日時: 2006-06-19 11:47
回答ではありませんが…。
引用:

まず実現したいと思ったのは次のようなことです。

・複数プロジェクトで同じ値を参照したい。
・Testクラスはすべてのプロジェクトでプロジェクト参照している。
・値はプロジェクト1でだけ設定される。
・他のプロジェクトはプロジェクト1で設定された値を参照するだけ。
(前のトピックでも書きましたが、みればみるほどグローバル変数っぽいな・・・)


これが最初の投稿に記載されていれば話の流れが変わっていたでしょうね。
# 因みにグローバル変数ってのも違う気がする…。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-06-19 12:16
引用:

にゃごさんの書き込み (2006-06-19 10:35) より:

これ(↓)ってありでしょうか?
(snip)
で、いろいろしつこくコードを試してみると、下記のようなコードで、やりたいことが実現できている(ように見える)のですが・・・。これってありでしょうか?


迷っている理由は、共有メンバでないコンストラクタで、共有メンバの値を設定しているからですよね?
値を設定するのはコンストラクタではなく、共有メソッドにすれば良いのではないでしょうか?

...もともとは、「他のプロジェクトから値の変更を許したくない」 という理由があって悩んでいたのだと思います。
共有メンバではなく、インスタンス メンバにしておいて、
'このクラス (Test) のインスタンス' を持つ変数を Shared に持てば良いのではないでしょうか?

いわゆる、グローバル的な使い方ですが...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌

スキルアップ/キャリアアップ(JOB@IT)