コードの違いは何ですか?

タグの編集
投稿者 超初心者  (社会人) 投稿日時 2020/5/4 00:12:30
すごく初歩的な質問ですがご容赦ください。

ボタンをクリックする等のイベントで、コーディングの最初に自動で (sender As Object, e As EventArgs)
と生成されます。

ですが色々なサイトを見ると (ByVal sender As System.Object, ByVal e As System.EventArgs) 
と記してあることが多いです。

どちらも問題なく実行できるので、バージョンの違いでVB2019から変更になったのだと推測していますが、詳しく解説しているサイトを発見できませんでした。

超初心者なもので気になります。
この違いは何でしょうか?
拙い文章で言葉足らずな部分が多々あるかと思いますが、回答いただけたら幸いです。
投稿者 るきお  (社会人) 投稿日時 2020/5/4 08:35:57
ByValの有無の違いについて

2点お伝えすることがあります。

1点目はsenderやeなどの引数の扱い方を示すキーワードとして、ByRef と ByVal があります。どちらも記述しなかった場合、ByVal が指定されたとみなされるということです。

つまり、もともと
(ByVal sender As ObjectByVal e As EventArgs) 


(sender As Object, e As EventArgs)

は同じ意味でした。


2点目は、ByRefを使うケースはほとんどなく、ByValを使うケースが圧倒多数ということです。

以上2点を背景として、2010年ごろに自動生成されるプログラムが短くなるようにByValを省略したほうがいいのではないかという提案が1ユーザーからMicrosoftに寄せられ、これがVisual Studio 2010 SP1で採用されました。
今でもこの2つは同じ意味なのでどちらを記述してもかまいませんが、自動生成されるプログラムはByValを省きます。

ByValとByRefの機能上の違いは、ByValの場合、呼び出されたプロシージャ(Sub ~ End Sub, Function ~ End Functionの塊)の中で、引数の値を変更した場合、呼び出し元には影響しないのに対し、ByRefは呼び出しもとの引数も変更されるという違いがあります。

キーワードは 値渡しと参照渡しです。
参考
http://rucio.o.oo7.jp/main/dotnet/shokyu/standard34.htm


System. の有無の違いについて

もう1つの違い System. の有無は、私はあまり意識したことはありませんでした。
もともとObjectやEventArgsを含め、すべてのクラスや構造体は何かの名前空間に属しており、同じ名前のクラスが別の名前空間に存在することもあります。
たとえば、Point構造体は System.Drawing名前空間のPointと、System.Windows名前空間のPointがあり、機能が微妙に違います。
このような同じ名前のクラスとの混同を避けるために、名前空間も含めたフルネーム(完全修飾名)でクラス名を記述することがしばしばあり、それがObjectとSystem.Object、EventArgsとSystem.EventArgsの違いです。つまり、記述方法が違うだけで同じことを表現しています。
投稿者 (削除されました)  () 投稿日時 2020/5/4 10:08:45
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/5/4 10:10:33
『記述方法が違うだけで同じことを表現しています』という点は
るきおさんの投稿の通りですが、少し修正・補足させてください。


> 名前空間も含めたフルネーム(完全修飾名)でクラス名を記述することがしばしばあり、
> それがObjectとSystem.Object、EventArgsとSystem.EventArgsの違いです。

上記は間違いとも言い切れませんが、正確では無いと思います。


確かに EventArgs と System.EventArgs の違いについては、
【名前空間の記述を省略しているかどうか】です。
(VB2010 以降では Global.System.EventArgs と書くこともできます)
記述が省略されているだけで、EventArgs と System.EventArgs は完全に同一です。


しかし Object と System.Object の関係は、それとは異なります。

Object と System.Object が完全に同一の物であるという点では変わりないのですが、
その理由は名前空間の指定が省略されているからではありません。
Object は「Visual Basic の組み込み型(プリミティブ型)」であり、
System.Object は「.NET Framework の型」という違いによるものです。


EventArgs は青緑で表示されていますが、
Object は青ですよね。
(先の回答では、この違いが考慮されていませんでした)

青緑 なのは「.NET のデータ型」を表しており、
青 の方は「VB のキーワード」を表しています。


VB の組み込み型である Integer 型は、.NET の System.Int32 構造体と完全に同一です。
VB の組み込み型である Date 型は、.NET の System.DateTime 構造体と完全に同一です。
VB の組み込み型である String 型は、.NET の System.String クラスと完全に同一です。
VB の組み込み型である Object 型は、.NET の System.Object クラスと完全に同一です。


sender As System.Object において、System 名前空間を省略するのであれば、
sender As [Object] のように記述することになります。(こうすれば、Object も青緑になります)
※この場合の角括弧は、VB のキーワードを識別子とするためのエスケープ表現です。

また、どうして System 名前空間を省略できるのかは、
プロジェクトのプロパティを開き、[参照]タブを開いたところにある
[インポートされた名前空間]の欄で「System」にチェック☑が付いているからです。



蛇足情報としてもう一つ。

イベント ハンドラーのコードにおいては、「ByVal の有無」「System. の有無」以外にも、
Form1_Load などにおいて「Handles MyBase.Load」と「Handles Me.Load」の違いが
生じるケースがあるのは御存じでしょうか。

たとえば、新規の Form で、コードエディタ上部のドロップダウンを
[プロジェクト名] / [(Form1 イベント)] / [Load]
と選んだ場合は「Me.Load」が使われます。

一方、フォームデザイナをダブルクリックしたり、
プロパティ ウィンドウの[イベント]から [Load]を選んだ場合には、
「MyBase.Load」が使われます。

MyBase と Me の違いは、継承フォーム利用時などに影響を与えるものですが、
利用頻度としては低いので、普段は気にしなくても問題ありません。
しかし厳密には別物ですし、自フォーム上に
「Public Shadows Custom Event Load As EventHandler」
などを書いていた場合、MyBase.Load と Me.Load は異なる結果になりえます。
投稿者 超初心者  (社会人) 投稿日時 2020/5/4 13:28:18
るきおさん、魔界の仮面弁士さん 早速のご返答ありがとうございます。
非常に詳しく解説してくださり感謝いたします。

いちいち立ち止まっていては進まないと要所要所に記載がありましたが、どうしても気になり質問させていただきました。

今後も些細なことで質問すると思いますが、よろしくお願いいたします。