2

所以我想为 API 已经密封的类型创建一个扩展方法。

如果您了解扩展方法,以下内容应该看起来很熟悉。

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

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

注意,要声明一个扩展方法,它需要是静态的,因为它需要是静态的,所以我通过 GameObject 类型访问的 List 必须是静态的。我希望每个游戏对象都有自己的成员列表。但是我很确定,因为这是一个静态字段,每个实例化的 GameObject 都将指向同一个静态成员列表。

那么我的假设是否正确?如果是这样,什么可能是替代方案?我想避免将 GameObject 放在也包含 memberList 的包装类中,因为 api 只允许在运行时检测和操作 GameObject。有一些方法可以通过 gameObject 反向引用包装类,但这会增加我想要避免的代码的复杂性。

4

5 回答 5

6

是的,如果你想在游戏对象之外保留一些东西并通过扩展方法访问它,它必须是静态的。

您可以使用字典将一个成员列表映射到每个游戏对象:

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 网站上的相关答案可能会有所帮助:http ://answers.unity3d.com/questions/22493/unity-3-sealed-class-gameobject-.html

似乎应该有办法使用内置脚本系统在 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 回答