【问题标题】:Member '<method>' cannot be accessed with an instance reference error in Singleton Unity在 Singleton Unity 中,因实例引用错误无法访问成员“<method>”
【发布时间】:2020-01-04 05:14:13
【问题描述】:

我在网站上多次看到这个问题,但大多数解决方案似乎表明我应该将其设为实例变量而不是静态变量。然而,Singleton 模式的全部意义在于始终引用的这个静态对象。以下是我看过的链接:

Member cannot be accessed with an instance reference; qualify it with a type name

Member '<method>' cannot be accessed with an instance reference

最后一个链接将我引向以下内容:

What does the 'static' keyword do in a class?

我觉得我确实理解这一点。 Singleton 的重点是所有类都共享这个实例,所以感觉很完美?我没看到问题?根据 Singleton 约定和坦率的逻辑,它应该是 static

我很团结,正在尝试为一些同学和我正在尝试制作的游戏制作库存系统。我已经设置了 InventoryUI,但是我想构建一个在游戏中始终存在的静态库存。 InventoryUI 将从这个 Singleton 类中提取必要的数据。

换句话说,PlayerInventory 将充当 InventoryUI 的后端。 PlayerInventory 将是一个单例,InventoryUI 将从 PlayerInventory 中提取必要的数据

这是我的 Singleton 类的相关代码:

public class PlayerInventory : MonoBehaviour
{
    private static PlayerInventory instance;

    private PlayerInventory() { }

    public static PlayerInventory getInstance()
    {
        if (instance == null)
            return instance = new PlayerInventory();

        return instance;
    }
}

这是我的 InventoryUI 类的相关代码:

public class PlayerInventoryUI : MonoBehaviour
{
    //Inventory Instance
    static PlayerInventory inventory;

    void Start()
    {
        inventory = inventory.getInstance(); 
        //cannot be accessed with an instance reference Error occurs here.
    }
}

如果可能,有人可以向我解释为什么会出现此错误以及可能的解决方案。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    该静态方法在类中,而不是在实例中。因此,将 InventoryUI 中的代码更改为:

    public class PlayerInventoryUI : MonoBehaviour
    {
        //Inventory Instance
        static PlayerInventory inventory;
    
        void Start()
        {
            inventory = PlayerInventory.getInstance(); 
            //works because static methods are called from the class
        }
    }
    

    我经常在 Unity 中使用单例,在 Quora 回答中分享了我的模式:https://qr.ae/TSqaWt

    哦,如果你的 Inventory 不在某个 GameObject Script 组件中,它就不需要从 MonoBehaviour 继承。如果您不需要使用 MonoBehaviour 之类的东西(例如让 Unity 调用 Update),最好只使用一个普通的 C# 类。

    如果您不想将其作为脚本组件,将其显示在检查器等中会很好,那么您不应该自己“新建”它,而是让 Unity 创建它并将实例分配给静态发生这种情况时参考。在 Awake() 中这样做很好,所以当其他脚本执行 Start() 时单例已经存在

    【讨论】:

    • 很高兴听到它有帮助 - 请注意添加的内容,在您的原始代码中,MonoBehaviour 的“新”可能会导致严重的错误
    • 是的,我一看到更新就更新了!感谢您的帮助!
    【解决方案2】:

    请尝试以下方法: 库存 = PlayerInventory.getInstance();

    您正试图在不允许的(未初始化的)实例变量上调用静态方法。正如错误提示的那样,静态方法必须使用类型(类)名称进行限定。

    你已经在一个非静态类中定义了一个静态方法,虽然它是完全合法的,但这两者应该被认为是独立的实体。静态方法只能访问类的静态字段,不能访问任何实例变量。静态数据成员的内存是单独分配的,与对象没有任何关系。

    以 String.Parse() 为例,您不会编写 mystring.Parse(),而是使用 String 类的静态方法 Parse,该方法始终可用且不需要新的字符串实例使用。

    希望这会有所帮助,如果有任何进一步的问题,我会尝试更好地解释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      相关资源
      最近更新 更多