2

したがって、API が封印している Type の拡張メソッドを作成したいと思います。

拡張メソッドについて知っている場合は、次のことは見覚えがあるはずです。

private static List<Member> memberList = new List<Member>();

public static List<Member> GetMemberList(this GameObject go)
{
    return memberList;
}

拡張メソッドを宣言するには、静的である必要があり、静的である必要があるため、GameObject タイプを介してアクセスするリストは静的である必要があることに注意してください。各 GameObject に独自のメンバー リストを持たせたいと考えています。ただし、これは静的フィールドであるため、インスタンス化されたすべてのゲームオブジェクトが同じ静的 memberList を指すことは間違いありません。

それで、私の仮定は真実でしょうか?もしそうなら、代替案は何ですか?この API では実行時に GameObject の検出と操作のみが許可されるため、memberList も保持するラッパー クラスに GameObject を配置することは避けたいと思います。gameObject を介してラッパー クラスを逆参照する方法はありますが、回避したいコードがさらに複雑になります。

4

5 に答える 5

6

はい、ゲーム オブジェクトの外部に何かを保持し、拡張メソッドを介してアクセスする場合は、静的にする必要があります。

辞書を使用して、1 つのメンバー リストを各ゲーム オブジェクトにマップできます。

private static Dictionary<GameObject, List<Member>> memberLists = new Dictionary<GameObject, List<Member>>();

public static List<Member> GetMemberList(this GameObject go) {
  return memberLists[go];
}
于 2012-08-28T00:24:30.350 に答える
2

Unity3で作業しているようです。UnityAnswers サイトには、役立つ可能性のある関連する回答があります

組み込みのスクリプト システムを使用して、Unity フレームワークに固有の必要な動作をアタッチする方法があるはずです。

于 2012-08-28T00:36:37.170 に答える
1

はい、あなたは正しいです。静的メソッドがある場合、そのクラスのすべてのインスタンスは同じデータを共有します。通話return memberList;は違法です。と同じでreturn this.memberList;ありthis、静的メソッドでは使用できません。代わりに、クラスを呼び出す必要があります: return GameObject.memberList;。しかし、あなたがこの解決策を探していないことは理解しています。

拡張メソッドは、追加の動作を作成するためのものです。追加のデータを作成する場合は、継承を使用して GameObject クラスを拡張するのが正しい選択です。

または、フォームの辞書を使用して memberList をアタッチすることもできますDictionary<GameObject, List<Member>>。しかし、個人的には、以下に示すような構成を好みます。

public class myGameObject
{
    public List<Member> memberList { get; set; }
    public GameObject go { get; set; }
}
于 2012-08-28T00:29:21.137 に答える
1
private static ConditionalWeakTable<GameObject, List<Member>> dict = new ConditionalWeakTable<GameObject, List<Member>>();

public static List<Member> GetMemberList(this GameObject go)
{
  return dict.GetOrCreateValue(go);
}

ConditionalWeakTable弱参照を使用するため、オブジェクトの有効期間を管理します。GameObjectしたがって、他にライブ参照がない場合でも、GC による の収集は停止されません。これにより、 のList<Member>収集も可能になります。

これはスレッドセーフですが、これは開始点を空のリストにすることを前提としています (GetOrCreateValue現在の値がない場合、デフォルトのコンストラクターが呼び出されます)。別の開始点が必要な場合は、スレッド化の問題がより複雑になります。

于 2012-08-28T00:40:51.457 に答える
0

拡張メソッドは、インスタンス メソッドのように "見える" 単なる静的メソッドです。

ただし、静的メソッドにはない追加機能は追加されません。これは、使いやすさ、メンテナンス、および読みやすさのためだけです。拡張メソッドは、保護された / プライベート メンバーにもアクセスできません。

GameObjectが実際にシールされていない場合(つまり、sealedキーワードがない場合)、継承するクラスを記述しGameObjectて、保護されたメソッド/フィールド/プロパティにアクセスできます。これは、あなた自身がこれらのオブジェクトを構築している場合にのみ機能します。

于 2012-08-28T00:25:48.990 に答える