よろしくお願いします。
Visual Studio 2003 のVB.NETの環境で、以下の関数を利用して、共有する変数(Boolean型)に
値を設定する処理を行いたいのですが、普通に、Objectに型変換してしまうと、値が代入されない
形になってしまい、いろいろやってみたのですが、うまくいかずに、こちらで、お知恵を拝借
したく、投稿させて頂きました、どうか、よろしくお願いします。
System.Threading.Interlocked.Exchange(ByRef Object, Object) As Object
---------抜粋したコード---------------------------------
Dim bThread_Err as Boolean
System.Threading.Interlocked.Exchange(Cobj(bThread_Err), True)
型変換してしまうと、bThread_Errに、Trueが入らないのですが、型変換しないと、暗黙的な変換が
できないということで、エラーになりますので、Option Strict On をはずすと、暗黙的に変換される
ことで、bThread_Errに、Trueが入るのですが、Option Strict Onのままで、どのように記述すれば
うまくいくのか、お知恵を拝借できたら、幸いですので、よろしくお願いします。
CType() 使ってもダメでしょうか?
編集 削除と言っても、渡したいだけならばの話です...
Source:-------------------------------------------------------------
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim bThread_Err As Boolean
Dim obj As Object
bThread_Err = True
obj = CType(bThread_Err, Object)
MessageBox.Show(obj.ToString())
End Sub
ご回答ありがとうございます。
System.Threading.Interlocked.Exchange(CType(Gbl_ErrFlgs, Object), True)
と修正してみてやってみても、やはり、Gbl_ErrFlgsにTrueが入らないようです。
Option Strict Onをはずすとうまくいくので、Option Strict Onを入れた状態でも、
記述をきちんと行えばGbl_ErrFlgsにTrueがきちんと入るのではないかと考えている
次第なのですが。
> System.Threading.Interlocked.Exchange(Cobj(bThread_Err), True)
これは、誤解される気が...。
えっと、Gbl_ErrFlgs は Object型で参照型。
で、Gbl_ErrFlgs に bThread_Err の値を渡したいのですよね?
Private Sub CatchReference(ByRef Gbl_ErrFlgs As Object)
Dim bThread_Err As Boolean
'/ 渡したい変数を True にしとく
bThread_Err = True
'/ CType でキャストして渡す方法
Gbl_ErrFlgs = CType(bThread_Err, Object)
'/ Interlocked.Exchange() メソッドは、こうやって使うのでは?
'System.Threading.Interlocked.Exchange(Gbl_ErrFlgs, bThread_Err)
'/ Gbl_ErrFlgs の値を表示
MessageBox.Show(Gbl_ErrFlgs.ToString())
End Sub
タイトルの、
> 型変換して、参照型の引数をうまく渡す方法は?
を改めて見て「参照型の引数」って、どの位置からなのかが気になりました。
# 何か、私が派手な誤爆をやらかしてるような気がします。
# あー怖いw
ご回答ありがとうございます。
私の方のタイトルのつけ方が適切でなかったかもしれないと反省しております、
すいません。
また、ソースの方も、省略しすぎていたみたいで、正確に伝わっていなくて
誠にすいません。再度、正確に書きますと、スレッドで、エラーがあったか
どうかの判定につかう共有する変数を、グローバル変数として
Dim Gbl_bThread_Err As Boolean
を宣言してありまして、各スレッドで、エラーがあった場合に
System.Threading.Interlocked.Exchange(Cobj(Gbl_bThread_Err ), True)
として、このグローバル変数に、Trueを入れたいという処理をしています。
最初の抜粋したコードですと、bThread_Errとなっていてローカル変数と
なっていましたので、誠にすいませんでした。
それで、ご指摘頂いたように、
Dim Gbl_bThread_Err As Objectとして
System.Threading.Interlocked.Exchange(Gbl_bThread_Err, True)
とすると、Trueが入って、問題がないのですが、Boolean型で事足りるので
できたら、Object型でなくBoolean型でグローバル変数のほうを持てたら
いいなと思い、Option Strict Onをはずすとうまくいくので、何か、記述を
変えれば、Option Strict Onを入れた状態でもうまくいくのかなと思い
試行錯誤しておりました。
System.Threading.Interlocked.Exchange(ByRef Object, Object) As Object
なので、こういう場合には、共有する変数は、素直に、Objectで持っておいた
ほうが賢明でしょうか(たとえ、True,Falseの二値しかつかわないとしても)
追加ですが。
Option Strict Onをはずすとうまくいった時のコードは、
System.Threading.Interlocked.Exchange(Gbl_bThread_Err, True)
でした。暗黙的に変換されるので、Option Strict Onがないとこれでも
通ってしまい、なおかつ、Gbl_bThread_ErrにTrueが入っているのですが、
それと、上記のDim Gbl_bThread_Err As Boolean は 正しくは
Public Gbl_bThread_Err As Booleanでした、急いでレスしたので、
間違えてしまい、申し訳ありません。
横から割り込んで申し訳ありませんが、
まず、整理してみましょうか...
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemthreadinginterlockedclassexchangetopic2.asp
「
Overloads Public Shared Function Exchange( _
ByRef location1 As Object, _
ByVal value As Object _
) As Object
」
を見てもらうと、
第一引数は、指定した値に設定する変数。
第二引数は、第一引数 パラメータに設定される値。
戻り値は、第一引数の元の値。
ですね。
Dim bThread_Err as Boolean
System.Threading.Interlocked.Exchange(bThread_Err, True)
とした場合、
Option Strict Onにした状態では、遅延デバインディングができませんので、型変換をしないといけませんね。
では、どうするのか?
Dim bThread_Err as Boolean
Dim OThread_Err as Object = Ctype(bThread,Object)
Dim ORet as Object = System.Threading.Interlocked.Exchange(OThread, True)
bThread_Err = Ctype(OThread_Err,Boolean)
とすることで解決しますが、スマートになりません。
と考えると、最初から、Object型で処理を行い、必要に応じてキャスト(CType)した方が処理効率が上がります。
納得してもらえたでしょうか?
回答ありがとうございました。
なるほど、非常に納得がいきました、サンプルで示して頂いたように、Boolean型で
宣言しておいて、処理できる事はできても、かなり煩雑になるので、言われるように、
Object型で宣言をしておいて、あとで、必要に応じてキャスト(CType)して処理の方が
煩雑にならずにすみそうですね。
そのように、処理の方をするように、書き換えてみようと思います。
じゃんぬねっとさん、ならびに、ぺがらぼさん、有難う御座いました。