【问题标题】:c#: check if a 'ref' argument actually comes from a static variablec#:检查“ref”参数是否实际上来自静态变量
【发布时间】:2018-12-01 10:19:19
【问题描述】:

有没有办法在函数中检查参数是否为静态变量?

这将帮助我防止任何拼写错误的可能性,其中用户尝试快速设置单例,但在通过 @ 提供给我们之前忘记将自己的 instance 成员声明为 static 987654324@

这是我的功能:

// returns 'false' if failed, and the object will be destroyed.
// Make sure to return from your own init-function if 'false'.
public static bool TrySet_SingletonInstance<T>(this T c,  ref T instance) where T : Component {

    //if(instance is not static){ return false } //<--hoping for something like this

    if(instance != null){  
        /* cleanup then return */
        return false;  
    }
    instance = c;
    return true;
}

【问题讨论】:

标签: c# unity3d


【解决方案1】:

如果我们假设您的单例类只有一个静态实例(这是有道理的,因为它是 singleton),我们可以使用类型找到字段。在这种情况下,实际上根本不需要在对它的引用中传递它。由于我们知道如何获取 FieldInfo,我们可以通过反射判断它是否是静态的。

public static bool TrySet_SingletonInstance<T>(this T c) where T : Component
{
    //Find a static field of type T defined in class T 
    var target = typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public).SingleOrDefault(p => p.FieldType == typeof(T));

    //Not found; must not be static or public, or doesn't exist. Return false.
    if (target == null) return false;

    //Get existing value
    var oldValue = (T)target.GetValue(null);

    //Old value isn't null. Return false.
    if (oldValue != null) return false;

    //Set the value
    target.SetValue(null, c);

    //Success!
    return true;
}

用法:

var c = new MySingleton();
var ok = c.TrySet_SingletonInstance();
Console.WriteLine(ok);

在此处查看工作示例:DotNetFiddle

【讨论】:

  • 我不明白的是,为什么你会有一种方法来设置单例而不是在 ctor 中分​​配单例?我没有看到其中的附加值。如果只是要知道分配是否通过,那么您可以检查 if(c == MySingleton.Instance),它会告诉您单例是否指向该实例对象。我觉得问题更多在于 OP 的设计。
  • 一个更好的问题是why would you use a singleton at all?
  • 本人在使用Unity,长期以来在构造函数方面遇到了一些问题。如果我记得的话,它们在编辑器期间在各种不方便的时间被调用,所以经过无数小时的黑客攻击,我将代码移到了其他仅运行时的 init 函数。这完全是关于初始化,以及许多脚本初始化的顺序,这些初始化必须间隔至少 2 帧。或许还有其他不记得的东西。
猜你喜欢
  • 1970-01-01
  • 2014-05-12
  • 1970-01-01
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
相关资源
最近更新 更多