C#Singleton:设计问题 [英] c# singleton : design question

查看:101
本文介绍了C#Singleton:设计问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

希望获得有关设计问题的帮助:
我有一个单例实例.

我正在考虑向其中添加一个成员:(x类的)实例数组,其中x是具有构造函数且可获取一些参数的类.

我希望数组中的每个单元格都具有延迟初始化.

我需要每个对象都是单例-但是在没有模式的情况下,是否有任何减少或简单的方法可以实现相同目的,整个阵列已经是单例的成员了?

在以下情况下,您会向我推荐什么设计模式:
1)访问数组对象必须是线程安全的
2)不需要输入安全类型

预先感谢任何想法\ suggestion

Hello everyone,

I would appreciate help with a design question:
I have a singleton instance.

I''m thinking of adding a member to it: an array of instances (of class x) where x is a class with constructor that gets some parameters.

I want each cell in the array to have lazy initialization.

I need each object to be singleton - but is there any reduction or simple way to achieve the same without the pattern the whole array is a member of a singleton already?

What design pattern would you recommend to me when:
1) Access to the array''s objects need to be thread safe
2) No need to be type safe

Thanks in advance to any idea\suggestion

推荐答案

我认为,由于您建议添加的新成员是单例对象的成员,因此它们实际上也会通过联系成为单身人士.在传统的单例模式中,您可以通过静态.Instance成员访问唯一的实例,该成员周围可以具有双重锁定模式:

http://msdn.microsoft.com/en-us/library/ff650316.aspx [ ^ ]

看一下多线程单例"部分.

希望对您有所帮助.
I would assume that because the new members you propose to add are members of a singleton object, that they will in fact also be singletons by means of association. in a traditional singleton pattern you access the only instance via the static .Instance member which can have a double locking patter around it:

http://msdn.microsoft.com/en-us/library/ff650316.aspx[^]

have a look at the section "Multithreaded Singleton".

hope it helps.


好吧,类似的事情可能就是您所追求的.在我的示例中,我假设ClassX 是每个单元格的类型,并且您要延迟初始化它是此类.顺便说一句,ClassX 在定义上不是单例的,因为您要具有该类的多个实例.加载主单例类时,请对要初始化的每个单元格调用AddCell .不会创建基础ClassX 实例,但我们存储必需的参数.以后,您可以调用GetCell 来获取每个单元格(ClassX instance),并将根据需要创建它.因此,那些您不访问的索引将不会初始化其单元格.您可以通过添加索引器来改善界面,该索引器将调用GetCell (这样可以更轻松地访问单元格),但这取决于您.如果您有任何问题,请告诉我.

Okay, something like this may be what you are after. In my example, I''ve assumed that ClassX is the type of each cell, and it''s this class that you want to lazy-initialize. By the way ClassX is not a singleton by definition, since you want to have multiple instances of that class. When you load up the main singleton class, call AddCell for every cell that you want to initialize. The underlying ClassX instance will not be created but we store the required arguments. Later, you can call GetCell to get each cell (ClassX instance) and it will be created on demand. So those indices that you do not access will not have their cells initialized. You can improve the interface by adding an indexer that will call GetCell (so it''s smoother to access the cells) but that''s up to you. Let me know if you have any questions.

public class ClassX
{
  public ClassX(int x, int y)
  {
      // some heavy initialization here
  }
}

public sealed class SingletonClass
{
  private class InnerClass
  {
      static InnerClass()
      {
      }

      public static readonly SingletonClass instance =
        new SingletonClass();
  }

  private SingletonClass() { }

  public static SingletonClass Instance
  {
      get
      {
          return InnerClass.instance;
      }
  }

  const int CellCount = 100;

  private ClassX[] cells = new ClassX[CellCount];

  private Dictionary<int, Tuple<int, int>> paramsMap =
    new Dictionary<int, Tuple<int, int>>();

  public void AddCell(int index, int x, int y)
  {
      // Todo: Add error check for the index (should be valid for the array)
      paramsMap[index] = Tuple.Create(x, y);
  }

  public ClassX GetCell(int index)
  {
      if (cells[index] == null)
      {
          if (paramsMap.ContainsKey(index))
          {
              // The cell is lazy constructed (on demand)
              cells[index] = new ClassX(
                paramsMap[index].Item1, paramsMap[index].Item2);
          }
          else
          {
              throw new InvalidOperationException();
          }
      }

      return cells[index];
  }
}




~~~~~~~~

如果希望GetCell 代码是线程安全的,则可以将其更改为:




~~~~~~~~

If you want the GetCell code to be thread-safe, you can change it to:

public ClassX GetCell(int index)
{
  lock (cells)
  {
      if (cells[index] == null)
      {
          if (paramsMap.ContainsKey(index))
          {
              // The cell is lazy constructed (on demand)
              cells[index] = new ClassX(
                paramsMap[index].Item1, paramsMap[index].Item2);
          }
          else
          {
              throw new InvalidOperationException();
          }
      }

      return cells[index];
  }
}



我的意思是说ClassX 在这种情况下不能是单例,是因为您有多个实例.也许您的意思是说,对于传递给它的每组唯一的参数,这都是一个虚拟的信号.如果真是这样,您将不得不编写代码来实现该检查,因为我的代码不会阻止他们添加两个或更多个具有相同参数的ClassX 实例.我希望这是有道理的.



And what I meant by saying that ClassX cannot be a singleton in this scenario is that you have multiple instances of it. Perhaps you mean to say that it''s a virtual-singleton for every unique set of arguments that you pass to that. If that''s the case, you''d have to write code to implement that check because my code will not prevent them from adding two or more ClassX instances with the same parameters. I hope that makes sense.


这篇关于C#Singleton:设计问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆