VS2003を使ってます。
VBはあまりよく知らなくて、
四苦八苦しています。
★1
Dim colorA = Color.Red
のようにAs Colorを記述するのを忘れている
のに、コンパイルが通ってました。
あれ?っと思ってました。
Option Strict On
をつけるとこれを抑止してくれるとわかり、
プロジェクトの設定で、つけるようにしました。
ところが、その弊害か?
引数として、Base型をとるメソッドにその派生型の
オブジェクトを引き渡すような呼び出しの
ところで、怒られてしまいました?
正確には、怒られたという1週間くらい前の記憶が
あります。
もしかしたら、ByValになってたからか?
BvRefだったら、OKなのか?
C++でポリモーを聞かすときは、Baseのポインタを
使うから。
これでは、ポリモーフィズムを効かすロジックが
書けないです。
★1のようなものを抑止しつつ、ポリモーフィズムを
効かすように、継承階層の上位の方向に対しては、
通常にキャストなしで、代入できる。
OOPとして、ごく普通のことをできるやり方を
教えて下さい。
No.2ベストアンサー
- 回答日時:
お世話になります。
どうも、仕様のようです。
http://msdn2.microsoft.com/ja-jp/library/d26b27b …
> じゃ、ByRefっていったいどんな時に使うものなんでしょう?
>
> 1)プリミティブについてのByVal
> 2)プリミティブについてのByRef
> 3)値型についてのByVal
> 4)値型についてのByRef
> 5)参照型についてのByVal
> 6)参照型についてのByRef
> (3)と(4)も基本的にそれと、同じイメージで
> 考えていいのでしょうか?
1) 2) が Integer 等を示していて、
3) 4) が 構造体 等の事を示されているのであれば、
そうだと思います。
私個人の経験ですが、
ByRef が必要な時ってあんまりないです。
関数を作る場合は、Return で値を返却するように
設計するのが標準的だと思っております。
ちなみに、値型以外のものを引数で渡す場合は
ポインタ渡しになります。
それで、
Dim frmTestForm As TestForm
Utils.CreateForm("TestForm", frmTestForm)
こちらの 2 行目を実行する際の
frmTestForm は 値もポインタも Null です。
なので、NullReference Exception が発生しているものと思われます。
返事が遅くなりました。
>どうも、仕様のようです。
そうでした。ByValで渡すとポリモーがききます。
ByRefでFormを要求しているパラメータに
FormAを与えてたとして、
メソッドの中でFormBに変更されてしまうと、
呼び元はFormA型なのに、FormBがはいってることになるという
変な状態になるような気がしてきました。
そのあたりの不都合を防止するための仕様のように感じました。
>関数を作る場合は、Return で値を返却するように
>設計するのが標準的だと思っております。
私も標準的だと思っていたのですが、
事情があって、そうすると面倒な変更がほかのところで発生
するので、あったので、さけたかったのですが、
結局、あきらめて、そうしました。
どうも、ありがとうございました。
No.1
- 回答日時:
お世話になります。
> 引数として、Base型をとるメソッドにその派生型の
> オブジェクトを引き渡すような呼び出しの
> ところで、怒られてしまいました?
いや、
下の例で言うと、AnimalCry メソッドへ
myCat を渡しているところが該当箇所だと思いますが
これは怒られないです。
Option Strict On
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim myDog As Animal = New Dog("taro")
Dim myCat As Cat = New Cat("hanako")
Me.AnimalCry(myDog)
Me.AnimalCry(myCat)
End Sub
Public Sub AnimalCry(ByVal ani As Animal)
Console.WriteLine(ani.Name)
ani.Cry()
End Sub
End Class
' 抽象動物クラス
Public MustInherit Class Animal
Protected m_name As String
Public ReadOnly Property Name() As String
Get
Return Me.m_name
End Get
End Property
Public Sub New(ByVal name As String)
Me.m_name = name
End Sub
Public MustOverride Sub Cry()
End Class
' 犬クラス
Public Class Dog : Inherits Animal
Public Sub New(ByVal name As String)
MyBase.New(name)
End Sub
Public Overrides Sub Cry()
Console.WriteLine("wan")
End Sub
End Class
' 猫クラス
Public Class Cat : Inherits Animal
Public Sub New(ByVal name As String)
MyBase.New(name)
End Sub
Public Overrides Sub Cry()
Console.WriteLine("nya")
End Sub
End Class
この回答への補足
例えば以下のようなコードがあります。
Option Strict Offで実行すると、
新たにTestFormをモーダルで起動してくれます。
CreateFormの中で、frmTestFormに実態を代入してくれることを期待しています。
戻ってきたら、
frmTestForm.ShowDialog()
でモーダル起動しています。
しかし、Option Strict Onにすると、コンパイラに
おこられてしまうので、
しぶしぶ、
Public Shared Sub CreateForm(ByVal ts As String, ByRef f As Form)
を
Public Shared Sub CreateForm(ByVal ts As String, ByVal f As Form)
と
ByVal f As Form
に変更して、実行しました。
すると、
frmTestForm.ShowDialog()
にて、NullReference Exception で怒られてしまいます。
実は事情があって、古いDelphiのコードをVB.NETに
コンバートしなければ、ならない部分があり、
その旧Delphiコードがメソッド内部で、値を代入する
イメージのロジックが結構あったんです。
リスクを回避するため、できるだけ、旧コードを流用したいので、そのままのイメージで変換したい。
しかし、Option Strict Onにひっかかってしまう!!
・質問文および、お礼で、質問している辺りの
知識が深く関係していると思うので、その辺りを
確認したかったのが、今回の質問の趣旨です。
Public Class TestForm
Inherits System.Windows.Forms.Form
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim frmTestForm As TestForm
Utils.CreateForm("TestForm", frmTestForm)
frmTestForm.ShowDialog()
End Sub
End Class
Public Class Utils
Public Shared Sub CreateForm(ByVal ts As String, ByRef f As Form)
f = CType(CreateInstance(ts), Form)
End Sub
Public Shared Function CreateInstance(ByVal ts As String) As Object
'//インスタンスを生成
'Dim sourcePageClassFullName As String = ""
Dim type As System.Type = System.Type.GetType(ts)
Dim obj As Object = type.InvokeMember(Nothing, _
System.Reflection.BindingFlags.CreateInstance, _
Nothing, Nothing, _
Nothing)
Return obj
End Function
End Class
さっそくありがとうございます。
↑ですが、うまく動いてるようです。
ただ、
Public Sub AnimalCry(ByVal ani As Animal)
を
Public Sub AnimalCry(ByRef ani As Animal)
とByRefに変更すると、
「Option Strict On で'Animal'から'Cat'への暗黙的な変換はできません。」と怒られてしまいます
どうやら、引数を与える時というより、
"メソッドの実装の中で実引数が更新される可能性があるシグニチャであるが、その際は、呼び出し元では、
Cat型ということになっているものにAnimalをキャストなしで、代入することになりますが、それは、Option Strict Onにひっかかるんじゃないですか?という意味内容の警告に見えます。
Animal自体がVB.NETでいうところの参照型なので、
ByValにしても、Animal* 型のイメージになるという
ことでしょうか?
だとすると、ByRefだと、Animal**のイメージなんですか?
じゃ、ByRefっていったいどんな時に使うものなんでしょう?
1)プリミティブについてのByVal
2)プリミティブについてのByRef
3)値型についてのByVal
4)値型についてのByRef
5)参照型についてのByVal
6)参照型についてのByRef
(1)と(2)の違いは、(2)では、いわゆるSwap関数を
実現するような時に違いがでるイメージに見えます。
(3)と(4)も基本的にそれと、同じイメージで
考えていいのでしょうか?
そして、(5)と(6)が、今回問題になってる違いですね?これは、いかに??
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(ビジネス・キャリア) 三国間貿易について 5 2022/05/26 14:18
- 仕事術・業務効率化 効率的な勉強方法(分野問わず)を教えてください 1 2023/08/16 01:33
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- 電車・路線・地下鉄 マニアに質問。JR電車内で車掌に乗り越し精算、乗車区間変更をお願いする時の事ですが・・・ 2 2022/10/02 20:58
- 認知障害・認知症 感情を抑える方法について 1 2023/05/19 20:42
- Visual Basic(VBA) VBA リボンののリカバリーでオーバーフローエラーになります 2 2023/07/04 19:07
- Visual Basic(VBA) countifsについての質問 3 2023/03/08 13:45
- その他(買い物・ショッピング) 1番は自転車通勤で日焼け対策のために日焼け防止効果のあるノースフェイスの上から羽織るものを探していま 1 2023/05/08 07:29
- Android(アンドロイド) android端末のアプリ移行について 5 2022/10/04 06:28
- その他(学校・勉強) この中で間違ってある説明はありますか?詳しい方に教えていただきたいです。 A. 1つのプログラムが複 2 2023/07/14 01:15
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Application.ScreenUpdating = ...
-
VBA他のブックから値のみ貼付す...
-
[python] 文字列を変数名として...
-
vbaでxmlからNodeListでデータ...
-
「*:*」って何を意味するのでし...
-
構造体の各データの表示につい...
-
セグメンテーション違反
-
VBAでPDFのコピーとリネームを...
-
PHP+MySQLでクロス集計は出来ま...
-
phpでボタンを押したときに変数...
-
似たようなコードを再利用する...
-
C言語の問題です
-
JSONで文字列が長い時
-
文字の横にプルダウンを表示さ...
-
セレクトメニューで2つの項目...
-
formで特定のinputを送信しない...
-
16進の10進変換について
-
<SELECT>タグの折り返し
-
【至急!!!】python言語で本を見...
-
関数「exists」と「defined」の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Application.ScreenUpdating = ...
-
実行時エラー 3020の対策
-
【メモリ不足で落ちる(python)】
-
パイソンのクラスのブログラム
-
パイソンのクラスについて
-
vscode 文字化け
-
パイソンプログラミング
-
VBAでPDFのコピーとリネームを...
-
FindFirst を複数条件で検索
-
ACCESS テキストボックスを隙...
-
[python] 文字列を変数名として...
-
構造体の各データの表示につい...
-
vbaでxmlからNodeListでデータ...
-
UWSC:ポップアップウインドウ...
-
コンボボックスのtag情報の取得...
-
phpでボタンを押したときに変数...
-
VBAで特殊文字を出力したい
-
VBA他のブックから値のみ貼付す...
-
C++ コマンドプロンプトでの入...
-
VB6のLSETをVB2005で実現するに...
おすすめ情報