ProgrammingVB.NET開発者、アーキテクト

Visual Basicにおける構造体(Structure)の特徴とクラス(Class)との正しい使用法を説明してください。適用時の制限は何ですか?および、メモリ管理と動作の観点からそれらはクラスとどのように異なりますか?

Hintsage AIアシスタントで面接を突破

回答

Visual Basicでは、構造体はStructureキーワードを使用して定義されます。これらは:

  • 値型(value type)である:スタック内または他のオブジェクトの内部に配置されます。
  • 他のユーザー定義型からの継承をサポートしていません(ただし、インターフェースを実装することはできます)。
  • 構造体本体の外部にある標準コンストラクタを除いて、引数のないコンストラクタを持つことはできません。
  • MustInherit(抽象)として宣言することはできず、ファイナライザを含むこともできません。
  • メモリを節約するための小さく変更不可能なオブジェクトに適した選択肢です。

Public Structure Point Public X As Integer Public Y As Integer Public Sub New(x As Integer, y As Integer) Me.X = x Me.Y = y End Sub End Structure Dim p1 As New Point(1, 2) Dim p2 = p1 ' 値がコピーされます、参照ではありません! p2.X = 5 ' p1.X = 1, p2.X = 5

制限

  • 構造体は互いに継承することはできず、System.ValueTypeのみから継承できます。
  • 引数のない自動コンストラクタのみが許可されています。
  • 実装のために許可されるのはインターフェースのみです。
  • 構造体が参照メンバーを含む場合、コピーや変異の可能性による注意が必要です。

トリック質問

Q: 構造体はByValとByRefで関数に渡すときどう振る舞いますか?クラスを渡す場合との違いは何ですか?

A: 構造体をByValで渡すと、構造体全体のコピーが作成されます。関数内での変更は元の値に影響しません。ByRefの場合は、元の変数が変更されます。クラスはどのような渡し方をしても(たとえByValでも)参照が渡されるのに対し、構造体はByValで完全にコピーされるため、パフォーマンスや動作に影響します。

Sub MutateByVal(p As Point) p.X = 100 End Sub Sub MutateByRef(ByRef p As Point) p.X = 100 End Sub Dim s As New Point(3, 4) MutateByVal(s) ' s.Xはまだ3 MutateByRef(s) ' s.Xは今100

歴史

1. 大規模なライブラリプロジェクトでは、構造体を使用してデータの大きな配列をByValでインターフェースに渡していました。これにより、大きな構造体がスタック上で何度もコピーされ、パフォーマンスが低下しました。この問題は、構造体を不変のクラスに置き換えることで解決されました。


歴史

2. GIS開発プロジェクトでは、参照フィールドを含む構造体のコピーで混乱が生じました。開発者は、構造体内の配列を変更しても、配列がコピーされた場所全てで元が変更されるとは予想していませんでした。


歴史

3. 会計ソフトウェアでは、ビジネスエンティティのために構造体とクラスを混在させていました。構造体に対する継承を実装しようとすると、コンパイルエラーが発生し、システムアーキテクチャを再編成する必要がありました。その初期の誤った選択のために、多くの労力が必要でした。