構造体とクラスを使用してUnityにデータを保存する際の注意事項

Unity では、struct と class の両方がカスタム タイプを定義するために使用されるキーワードです。主な違いは、インスタンスがどのように格納され、渡されるかです。

特徴 struct class
保管方法 値のタイプ 参照タイプ
デフォルトのコンストラクタ 自動 もつ
パフォーマンス 素早い 遅い
Null可能性 空ではない
継承する 単一継承 単一継承または多重継承

1. 類似点

1. どちらも、カスタム タイプを定義するために使用されるキーワードです。
2. 両方とも、フィールド、プロパティ、メソッド、コンストラクタなどのメンバーを含めることができます。
3. 継承、ポリモーフィズム、インターフェイスの実現など、オブジェクト指向プログラミングの特性をすべてサポートします。
4. どちらもメソッドのパラメーターと戻り値の型として使用できます。

2.違い

  • ストレージ メソッド
    クラスは参照型で、そのインスタンスはヒープに格納され、変数はインスタンスへの参照を格納します。構造体は値型ですが、そのインスタンスはスタックまたはヒープ上の値型オブジェクトに格納され、変数ストアはインスタンス自体の値。
  • デフォルトのコンストラクタ
    class にはデフォルトの引数なしのコンストラクタがありますが、struct にはありません。構造体を定義してコンストラクターを指定しない場合、コンパイラーはデフォルトの引数のないコンストラクターを自動的に生成します。
  • パフォーマンス
    クラスは参照型であるため、各インスタンスは参照を格納する必要があるため、一般に構造体よりもメモリを集中的に使用します。また、クラスのインスタンスを渡す場合、オブジェクト全体ではなく、参照のみが実際に渡されます。つまり、渡されたクラス インスタンスに変更が加えられると、元のオブジェクトも影響を受けます。対照的に、構造体は値型であり、渡されるとコピーされるため、特に大量のデータを処理する場合にパフォーマンスの問題が発生する可能性があります。
  • Nullability
    クラスは null に設定できますが、構造体はできません。場合によっては null 値を使用する必要がある場合は、クラスを使用する必要があります。
  • 継承
    クラスは単一継承と多重継承をサポートしますが、構造体は単一継承のみをサポートします。
    Unity では、ゲーム オブジェクトとコンポーネントは参照型であるため、Unity の参照型メカニズムをより有効に活用するために、クラスを使用してカスタム コンポーネントとスクリプトを定義することが一般的に推奨されます。ただし、構造体を使用して、オブジェクトを頻繁に作成および破棄する必要がある場合や、大量のデータを処理する必要がある場合など、特定の状況でパフォーマンスを向上させることもできます。

3. 使用シーンの提案

Unity では、struct と class を使用することには、長所と短所、および適用可能なシナリオがあります。以下は、適切な状況に適切なタイプを選択するのに役立ついくつかの使用方法の提案です。

  • 構造体用

1. ベクトル、行列、色などの小さなデータ型に適しています。これらの型は通常、不変です。つまり、作成後に値が変更されることはありません。
2. オブジェクトの作成と破棄が頻繁に必要なシナリオや、大量のデータを処理する必要があるシナリオなど、高いパフォーマンスが要求されるシナリオに適しています。構造体は値型であるため、渡されるとコピーされ、特に大量のデータを処理する場合にパフォーマンスの問題が発生する可能性があります。
3. スレッドの安全性を確保する必要があるシナリオに適用できます。構造体は不変であるため、ロックやその他の同期メカニズムを使用する必要なく、マルチスレッド環境で安全に共有できます。
4. 構造体に多数のフィールドまたは配列を含めないようにします。構造体はスタックまたはヒープ上の値型オブジェクトに格納されるため、そのサイズはメモリ使用量に直接影響します。

  • 授業のために

1. カスタム コンポーネントやスクリプトなど、より複雑なデータ編成と処理ロジックを必要とするシナリオに適用できます。クラスは参照型であるため、Unity の参照型メカニズムをより有効に活用できます。
2. プレハブのインスタンス化、ゲーム オブジェクトの管理など、オブジェクトを動的に作成および破棄する必要があるシーンに適用できます。
3. 継承、ポリモーフィズム、インターフェース実装などのオブジェクト指向プログラミング機能を必要とするシナリオに適用できます。
4. 継承や入れ子になった型を過度に使用しないでください。過度に複雑になり、コードの保守が困難になる可能性があります。

つまり、構造体またはクラスの選択は、特定のニーズとシナリオによって異なります。実際の開発では、最適なパフォーマンスと保守性を得るために、実際の状況に応じてトレードオフと選択を行う必要があります。

4. 注意事項の例

  • Linq の ForEach で使用する場合
using System;
using System.Collections.Generic;
using System.Linq;

public struct Item
{
    
    
    public int Id;
    public string Name;
}

public class ExampleClass
{
    
    
    private List<Item> items = new List<Item>
    {
    
    
        new Item {
    
     Id = 1, Name = "Item 1" },
        new Item {
    
     Id = 2, Name = "Item 2" },
        new Item {
    
     Id = 3, Name = "Item 3" }
    };

    public void IterateList()
    {
    
    
        items.ForEach(item =>
        {
    
    
            Console.WriteLine($"Item ID: {
      
      item.Id}, Name: {
      
      item.Name}");
            item.Name = null;//此处没有修改数据源,修改的传入的副本
        });
    }
}

同様に、 foreach の使い方も同じです。
以下のコードの項目も構造体の単なるコピーです。

foreach (var item in items)
{
    
    
      Console.WriteLine($"Item ID: {
      
      item.Id}, Name: {
      
      item.Name}");
  }

おすすめ

転載: blog.csdn.net/dzj2021/article/details/130217920