【问题标题】:Output parameter in a Singleton单例中的输出参数
【发布时间】:2013-12-19 19:25:27
【问题描述】:

以下胎面在单例模式中是否安全?我在http://csharpindepth.com/Articles/General/Singleton.aspx中使用了第四个单例模式

我担心使用输出参数会破坏整个主体。

public sealed class eCacheContent
{
        private static readonly eCacheContent instance = new eCacheContent();
        private ICacheManager _Cache = CacheFactory.GetCacheManager(ConfigurationManager.AppSettings["ContentCache"].ToString());
        // for access method control locking
        private static object syncRoot = new object();

        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static eCacheContent() { }

        private eCacheContent() { }

        public static eCacheContent Instance
        {
            get
            {
                return instance;
            }
        }

        public bool TryGetValue(string key, out eContent output)
        {
            lock (syncRoot)
            {

                if (Contains(key))
                {
                    ObjectCloner helper = new ObjectCloner();
                    eContent tmp = (eContent)this._Cache.GetData(key);
                    output = helper.Clone(tmp);
                    return true;
                }


                output = new eContent();
                return false;
            }
        }

        public void Add(string key, object value)
        {
            // Initiase the helper class for cloning
            if (CheckKeyIfValid(key))
            {
                ObjectCloner helper = new ObjectCloner();
                // Remove if already exist
                this.Remove(key);
                // Add carbon copy
                _Cache.Add(key, helper.Clone(value));
            }
        }

        public void Flush()
        {
            _Cache.Flush();
        }

        private bool Contains(string key)
        {
            if (CheckKeyIfValid(key))
                return _Cache.Contains(key);
            else
                return false;
        }

        private void Remove(string key)
        {
            if (Contains(key))
            {
                _Cache.Remove(key);
            }
        }

        private bool CheckKeyIfValid(string key)
        {
            if ((key != null) && (key.Trim().Length != 0))
                return true;

            return false;
        }

    } 

【问题讨论】:

  • 您的方法是 instance 方法,而不是 static - 我认为这是一个错误?
  • 我会说这确实是个坏主意。当您锁定此代码时,可能有其他线程正在访问您的“out”-ed 变量。切勿尝试锁定此 var,因为这可能会导致死锁。所以我会说:坏主意。无论如何,为什么要使用 ref 呢?只需返回字符串。这不是 c++,成员是引用计数的。
  • 我知道我的想法哪里出了问题。看看外面总是有帮助的......谢谢
  • @Samuel OP 并未锁定该变量,但他们有一个特定的 syncRoot 对象用于锁定。 “这不是 C++,成员被引用计数” - 这也不准确,C#使用引用计数,GC 在收集期间遍历对象图并处理任何无法到达的对象。
  • @James 感谢您指出这一点。我实际上知道 GC 会删除所有非根对象。但恕我直言,在更广泛的意义上,这可以被视为引用计数,其中引用表示根对象的任何路径(计数为 1),如果没有,则为 0:/ 但你是对的,我的解释不好。

标签: c# singleton


【解决方案1】:

我担心使用输出参数会破坏整个主体。

您认为out 参数在哪些方面违反了单例的原则?通过 definition 一个单例类“将类的实例化限制为一个对象” - 您的 Instance 属性确保了这一点。

您的TryGetValue 方法是用于提取eContent 的缓存版本的辅助方法,它与您的eCacheContent 类完全分开。

【讨论】:

  • 是的,我知道只有一个。从未在任何示例中看到输出参数,并且不确定它是否可以在用户之间共享,以防碰撞头。由于所有内容对象都被缓存,我预计这个单例会有很多流量。
猜你喜欢
  • 2012-12-09
  • 1970-01-01
  • 2017-03-16
  • 2010-11-06
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多