Visual Basic 中学校 掲示板 投稿内容
タグのない投稿を抽出 統計 RSS

Visual Basic 中学校 > 投稿一覧 >

値を返すクラス作成 解決済み

タグの編集...

投稿者 こじろー   (社会人)   投稿日時 2022/1/19 12:13:14
Public Class kifu_n
    Dim kifu_no As String = ""
    Dim AI_result_output = True
    Sub New(ByRef A As AI_Cell)
        Dim i As Integer = 0
        Dim XSTR(7) As String, YSTR(7) As String
        XSTR(0) = "a"
        XSTR(1) = "b"
        XSTR(2) = "c"
        XSTR(3) = "d"
        XSTR(4) = "e"
        XSTR(5) = "f"
        XSTR(6) = "g"
        XSTR(7) = "h"
        YSTR(0) = "1"
        YSTR(1) = "2"
        YSTR(2) = "3"
        YSTR(3) = "4"
        YSTR(4) = "5"
        YSTR(5) = "6"
        YSTR(6) = "7"
        YSTR(7) = "8"
        For i = 0 To 7
            If A.Position.X = i Then
                kifu_no &= XSTR(i)
            End If
        Next
        For i = 0 To 7
            If A.Position.Y = i Then
                kifu_no &= YSTR(i)
            End If
        Next
    End Sub

    Function get_zahyo() As String
        Return kifu_no
    End Function

    Function get_AI_result() As Boolean
        Return AI_result_output
    End Function

End Class

Dim kifu_n As kifu_n
AI_str_z1 = kifu_n.get_zahyo
で、最後から2行目の、 kifu_n で緑マークの警告で、値が使用される前に指定されています・・となります。

投稿者 魔界の仮面弁士   (社会人)   投稿日時 2022/1/19 13:25:36
> Dim kifu_n As kifu_n
> AI_str_z1 = kifu_n.get_zahyo
> で、最後から2行目の、 
「Dim kifu_n As kifu_n」というコードは無いようですよ?
「Dim kifu_no As String = ""」ならありますけど…。

> kifu_n で緑マークの警告で、値が使用される前に指定されています・・となります。
転記頂いた警告文が微妙に誤記っている気がしなくも無いですが、警告文に書かれている通りの事象です。
下記の変数 c でも同じメッセージが表示されますが、何故問題視されているのか分かりますか?

Dim a As String = "ABC"
Dim b As String = a & "D"  'これは b = "ABCD" になりますね 

Dim c As String  '初期値をセットしていない 
Dim d As String = c & "X"  '警告BC42104 
'変数 `c` は、値が割り当てられる前に使用されています。 




> Public Class kifu_n
>  Dim kifu_no As String = ""
>  Dim AI_result_output = True
フィールド変数は Dim と書くのではなく、Private/Friend/Public 等を使い分けた方が良いですよ。


> Sub New(ByRef A As AI_Cell)
この実装において
 Sub New(ByRef A As AI_Cell)
と書くことはデメリットしかありません。この場合には
 Sub New(A As AI_Cell)
もしくは
 Sub New(ByVal A As AI_Cell)
にすることを強くおすすめします。ByVal と ByRef の違いは分かりますか?


もう一つ。For のループカウンタ変数 i を
> Dim i As Integer = 0
のように記述するのは VB .NET 2002 までの古い書き方であり、現在は望ましくありません。

変数 i はループ内でしか使われていないので、この場合は
「Dim i As Integer」の行を削除しておくことをお奨めします。

そうすると、
> For i = 0 To 7
の部分は、自動型推論によって
 For i As Integer = 0 To 7
と書いてあるのと同じ意味であるものとしてコンパイルされます。

「For i As Integer = 0 To 7」という書き方は、VB .NET 2003 から導入されました。
この場合、変数 i が For ループ内のみ有効な局所変数になるため、
ループの外で誤って変数 i が操作されてしまう心配もありません。
変数の有効範囲(いわゆる "スコープ" )は、極力狭くした方が望ましいです。


なお、本来は「For i As Integer = 0 To 7」と書くべきところですが、VB2008 以降では
「For i = 0 To 7」が「For i As Integer = 0 To 7」の意味になり、
「Dim x = "TEST"」が「Dim x As String = "TEST"」の意味になるという
『型推論』という機能が実装されているため、現在のバージョンでは
「For i As Integer = 0 To 7」と書くよりも
「For i = 0 To 7」と書くことが多いです。(意味は同じ)

投稿者 こじろー   (社会人)   投稿日時 2022/1/19 14:21:05
>「Dim kifu_n As kifu_n」というコードは無いようですよ?
Dim kifu_n As kifu_n
AI_str_z1 = kifu_n.get_zahyo
の最後の行のkifu_nが緑の警告で、
警告 1 数 'kifu_n' は、値が割り当てられる前に使用されています。Null 参照の例外が実行時に発生する可能性があります。
です。
失礼しました。
kifu_nのクラスの中に、処理するものを書く必要があるのかと思うのですが・・

投稿者 こじろー   (社会人)   投稿日時 2022/1/19 14:32:01
http://vbnettips.blog.shinobi.jp/other/%E9%96%A2%E6%95%B0%E3%81%AE%E6%88%BB%E3%82%8A%E5%80%A4%E3%81%8C%E3%82%AF%E3%83%A9%E3%82%B9%EF%BC%88%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%EF%BC%89%E3%81%AE%E5%A0%B4%E5%90%88%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
に書いてあるようなのですが、少し理解ができません。

投稿者 KOZ   (社会人)   投稿日時 2022/1/19 14:42:06
Visual Basic 中学校 > 初級講座 [改訂版] >「第6回 クラスの使い方」
https://www.umayadia.com/VBStandard2/Standard06.htm

このあたりが理解できてないように思えます。読んでみてください。



投稿者 魔界の仮面弁士   (社会人)   投稿日時 2022/1/19 15:14:04
> Dim kifu_n As kifu_n
> AI_str_z1 = kifu_n.get_zahyo

まず、『Dim 変数名 As クラス名』の宣言において、
変数名とクラス名を同じ名前にするのはやめましょう。
間違いではありませんが、混乱の元です。

たとえば下記のコードは間違いではありませんが、このフォーム内の処理で
単に「Form1」と書いた時に、何を指しているのか分かりにくくなりますよね。

Public Class Form1
    Dim Form1 As Form1
End Class



> 警告 1 数 'kifu_n' は、値が割り当てられる前に使用されています。Null 参照の例外が実行時に発生する可能性があります。
「数」ではなくて「変数」ですよね…?

ざっくり言えば、【変数の初期化漏れ】を注意されています。

変数 kifu_n には、まだ何も代入されていない状態なのに、
それの get_zahyo を呼び出そうとしたことを警告されています。


'これだと、変数 a に対して同じ警告が出る 
Dim a As kifu_n
AI_str_z1 = a.get_zahyo()  '実行すると、Null 参照の例外「NullReferenceException」が出る 


'使用前に変数 b に値をセットしてあるので、もう警告は出ない 
Dim b As kifun_n
b = Nothing
AI_str_z1 = c.get_zahyo()  'でも Nothing のままなので、やはり Null 参照の例外「NullReferenceException」 


'変数 c に値がセットされているので、警告は出ない 
Dim c As kifun_n
c = New kifun_n(データ)    'kinfun_n を実体化したもの(インスタンス)をセットしている 
AI_str_z1 = c.get_zahyo()  '実体を参照しているので、もう Null 参照の例外は出ない 


'変数 d に値がセットされているので、警告は出ない 
Dim d As kifun_n = New kifun_n(データ)    '宣言と代入を一行で書いた場合 
AI_str_z1 = d.get_zahyo()  '例外は出ない 


'変数 x に値がセットされているので、警告は出ない 
Dim x As New kifun_n(データ)    '上記 d をこのようにまとめて書いてもよい 
AI_str_z1 = x.get_zahyo()  '例外は出ない 




なお、上記で「New kifun_n(データ)」と書いていますが、最初に提示して頂いたコードでは
>>> Sub New(ByRef A As AI_Cell)
と書かれていたかと思います。ですので、「New kifun_n(データ)」のデータ引数には、
あらかじめ用意しておいた『AI_Cell 型の変数』を渡すようにしてください。

もしも AI_Cell が Structure ではなく Class である場合は、
その変数に対して、上記同様にインスタンスをセットしておかないと
Null 参照の例外「NullReferenceException」となってしまう事にもご注意を。

投稿者 こじろー   (社会人)   投稿日時 2022/1/19 16:00:22
http://rucio.a.la9.jp/main/shokyu/jugyou27.htm
をひな型にして、解決しました。
以下です。
メイン
 Dim kifu_n As kifu_n
 kifu_n = New kifu_n
 AI_str_z1 = kifu_n.kifu(AI_select_cell, AI_result_output)

クラス
Public Class kifu_n
    Public Function kifu(ByRef A As AI_Cell, ByRef AI_result_output As Boolean) As String
        AI_result_output = True
        Dim kifu_no As String = ""
        Dim i As Integer = 0
        Dim XSTR(7) As String, YSTR(7) As String
        XSTR(0) = "a"
        XSTR(1) = "b"
        XSTR(2) = "c"
        XSTR(3) = "d"
        XSTR(4) = "e"
        XSTR(5) = "f"
        XSTR(6) = "g"
        XSTR(7) = "h"
        YSTR(0) = "1"
        YSTR(1) = "2"
        YSTR(2) = "3"
        YSTR(3) = "4"
        YSTR(4) = "5"
        YSTR(5) = "6"
        YSTR(6) = "7"
        YSTR(7) = "8"
        For i = 0 To 7
            If A.Position.X = i Then
                kifu_no &= XSTR(i)
            End If
        Next
        For i = 0 To 7
            If A.Position.Y = i Then
                kifu_no &= YSTR(i)
            End If
        Next
        kifu = kifu_no
    End Function
End Class