1

我正在使用 C# webforms 构建一个 Intranet。我有一个列表对象,其中包含我正在缓存的一堆用户。我正在尝试创建一个构造函数,当我引用 MainADList 时将执行以下操作:

  1. 如果它存在于缓存中且不为空,则使用它
  2. 否则生成列表并缓存它

我有代码来进行缓存和检索,但它没有以我想要的方式很好地封装。

public Users MainADList = new Users();

private void GenerateADList()
{
    MainADList = (Users) Cache["MainADList"];

    if (MainADList == null || MainADList.Count == 0)
    {
       //generate the list....

       Cache["MainADList"] = MainADList;
    }
 }

谢谢!

4

3 回答 3

6

您不能创建执行此操作的构造函数。构造函数总是创建一个新对象。

相反,创建一个静态工厂方法:

public static Users GetUsers()
{
    // Consult the cache, and create a new instance if necessary.
}

可能是一个单例- 但它肯定不是必须的。(除非我真的必须这样做,否则我不会人为地强加它的单例。我不是单例模式的忠实粉丝。)

或者,您可以在工厂类中使用实例方法,而不是静态工厂方法:

public class UsersFactory
{
    // Construct it with a cache, or whatever's required

    public Users GetUsers()
    {
        // Use the cache, or construct a new value.
    }
}

现在这更可测试 - 因为您不依赖任何静态(全局)状态。相反,您可以在每个测试中从新缓存创建新工厂。

所有这些解决方案中,您需要考虑您想要什么样的线程行为。如果要确保只构造一次值,则需要使用Lazy<T>静态初始化程序保证或锁定。

于 2013-01-15T17:46:48.613 回答
0

您可以遵循的一种通用模式:

public class ClassName {
  public static Object CachedObject {
    get {
      Object o = (Object)Cache['CacheKey'];
      if (o == null)
      {
         o = GetData();
         Cache["CacheKey"] = o;
      }
      return o;
    }
  }
}

并且将ClassName.CachedObject视为它始终、永恒且神奇地填充。

于 2013-01-15T17:52:23.843 回答
-3

你想要的是一个单例。

基本上你应该用你已经拥有的代码做的是这样的:

public static GetList
{
   get 
      {
          //check if list exists and create it - so basically call your private constructor
          //return cached list
      }
}
于 2013-01-15T17:44:44.577 回答