C# 直接访问静态类还是缓存静态类?

C# 直接访问静态类还是缓存静态类?,c#,caching,unity3d,C#,Caching,Unity3d,我知道,如果您在运行时经常使用组件,则最好缓存该组件。如果我将一个组件缓存为静态变量并在运行时访问它呢?让我举个例子: public class AudioManager : MonoBehaviour { public static AudioManager audioManager; void Awake() { audioManager = this; } } 那么,如果我从另一个类访问它,我应该使用AudioManager.AudioM

我知道,如果您在运行时经常使用组件,则最好缓存该组件。如果我将一个组件缓存为静态变量并在运行时访问它呢?让我举个例子:

public class AudioManager : MonoBehaviour
{
    public static AudioManager audioManager;

    void Awake()
    {
        audioManager = this;
    }
}
那么,如果我从另一个类访问它,我应该使用
AudioManager.AudioManager
还是事先缓存它(就性能而言)

如果有什么不清楚的地方,请告诉我

编辑:我想我不知道我到底在做什么关于单身,但要说清楚,这是一个关于性能的新手问题:

1)
\u audioManager=audioManager.audioManager
处于唤醒状态,然后在更新中使用
\u audioManager.someVariable

VS

2)
AudioManager.AudioManager.someVariable
在更新中

在任何情况下,您都不需要缓存自己的组件来提高速度。组件不会因为访问自身而支付性能损失

您可能考虑的用例是缓存对其他组件或对象的访问,这样您就不必使用GetComponent或GetComponentWithChildren进行查找。这确实节省了时间,但这不是一个复杂的模式:只要在第一次遇到其他组件或游戏对象时进行查找,将其存储在该组件内的字段中,就可以了:

 class Example: MonoBehavior
 {

     public GameObject _TargetCharacter;
     private Transform _cachedTransform;
     private Animator  _cachedAnimator;

     void Awake()
     {
      if (_TargetCharacter != null)
      {
          _cachedTransform = _TargetCharacter.transform;
          _cachedAnimator = _TargetCharacter.GetComponent<Animator>();
       }
     }


     void Update()
     {
         DoSomething (_cachedTransform, _cachedAnimator);
     }
 } 
类示例:单行为
{
公共游戏对象_TargetCharacter;
私有转换_cachedTransform;
私人动画师;
无效唤醒()
{
如果(_TargetCharacter!=null)
{
_cachedTransform=\u TargetCharacter.transform;
_cachedAnimator=_TargetCharacter.GetComponent。两种方法的目的相同,优势和劣势略有不同

针对OP的评论更新如下:

如果原始代码的目的是使用通用的Unity缓存技巧来提高速度,那么就不需要了。如果正如OP在下面的评论中所建议的那样,目的是让manager成为其他类可以调用的“服务提供者”,那么有两条路要走:

标准的unity技巧是将缓存行为添加到需要访问AudioManager的其他类中。例如:

class SomeOtherComponent: MonoBehavior
{
    AudioManager _manager;
    void Awake()
    {
    AudioManager[] AllAudioManagers = GetComponents<AudioManager>();
    if (AllAudioManagers.Count == 1)
        {
        _manager = AllAudioManagers[0];
        }
    else
        {
         throw new RuntimeError ("Expecting one (and only one) AudioManager in scene");
        } 
    }
}
class SomeOtherComponent:monobhavior
{
音频经理(AudioManager);;
无效唤醒()
{

AudioManager[]AllaudioManager=GetComponents

我遵循一个简单的规则,如果我要多次调用一个组件,超过5次,那么我会缓存它。我对单例应用相同的规则。如果只有一次调用,那么我只使用
Singleton.getInstance()


你真正应该做的是什么 Unity组件,例如


缓存类如“代码>转换/代码>的逻辑来自于查看文档。转换不是一个变量,而是一个属性,它包含了吸气剂和设置器。这些是隐藏的,但是这是实现的方式。这个属性恰好是用C或C++编写的。因此这将使你付出代价。ce.

您正在寻找吗?您需要多个
AudioManager
实例还是只需要一个实例?您应该将属性与非公共setter一起使用,以避免
AudioManager.AudioManager=null
以外的情况。如果缓存不足意味着延迟执行,则使用
惰性
。如果您需要单个对象ct,然后使用
static
provider或@srramsakthivel,仅一个实例。@那么我的链接应该对您有所帮助,我的意思是
\u audioManager=audioManager.audioManager;
在唤醒中,然后使用
\u audioManager.someVariable
在更新VS
audioManager.audioManager.someVariable中,您不需要cach在任何情况下都可以使用自己的组件来提高速度。组件不会因为访问自身而支付性能损失
你有证据吗?你不会因为调用
变换而支付费用。定位
而不是缓存自己的变换?
组件。变换
使用反射从父游戏对象获取变换,因此你确实想缓存它。但是如果你声明自己的字段并访问它们(就像OP那样)没有任何节省。检查@theodox上的措辞,我知道有某些模式和安全的方式来做某事。但在我的情况下,我有一个带有AudioManager脚本的游戏对象,它将保存对一堆音频源的引用。除了我之外,没有人会接触代码或项目。我不会添加其他AudioMan我这样做是为了打电话给AudioManager.AudioManager.SomeAudioClip.Play()从任何其他脚本播放声音,而不使用GetComponent和GameObject.Find。许多人似乎建议我实现一个单例模式,但我的代码按原样工作,我试图理解为什么在我的情况下实现它会有任何不同。考虑到我使用它的方式,我的代码会出什么问题ort版本:您发布的代码可以工作,但没有额外的好处,因为您正在“缓存”您已经可以快速访问的内容。对于需要确保多个组件共享对一个共享状态的访问的人来说,单例模式很重要(例如,你不希望一堆人工智能都使用相同的游戏地图数据,而不是可能失去同步的单独副本)。你的原始代码有点误导,因为它看起来像一个典型的单例,但(除非我错了)这只是为了让公众访问你的类。请参阅上面的编辑