在C#2.0中初始化非空静态集合的正确方法是什么?

时间:2009-01-05 16:37:02

标签: c# collections

我想在我的C#类中初始化一个静态集合 - 如下所示:

public class Foo {
  private static readonly ICollection<string> g_collection = ???
}

我不确定这样做的正确方法;在Java中我可以做类似的事情:

private static final Collection<String> g_collection = Arrays.asList("A", "B");

C#2.0中是否有类似的结构?

我知道在C#/ .NET的更高版本中,您可以执行集合初始值设定项(http://msdn.microsoft.com/en-us/library/bb384062.aspx),但目前我们的系统无法进行迁移。

澄清我原来的问题 - 我正在寻找一种方法来简洁地声明一个简单的静态集合,例如简单的常量字符串集合。对于更复杂的对象集合,静态初始化器方式也非常好。

谢谢!

9 个答案:

答案 0 :(得分:27)

如果我完全理解你的问题,似乎有些人错过了这一点,你希望以类似于Java的方式创建静态集合,因为你可以在一行代码中声明和填充而不必创建一个专门的方法来执行此操作(根据其他一些建议)。这可以使用数组文字(用两行代码来防止滚动)来完成:

private static readonly ICollection<string> Strings = 
  new string[] { "Hello", "World" };

这将同时使用项目列表声明和填充新的只读集合。在2.0和3.5中工作,我测试它只是为了加倍确定。

在3.5中虽然你可以使用类型推断,所以你不再需要使用string []数组来删除更多的击键:

private static readonly ICollection<string> Strings = 
  new[] { "Hello", "World" };

注意第二行中缺少的“字符串”类型。字符串是从数组初始值设定项的内容自动推断出来的。

如果您想将其填充为列表,只需为新列表更改新字符串[] a la:

private static readonly ICollection<string> Strings = 
  new List<string>() { "Hello", "World" };

当然,因为你的类型是IEnumerable而不是特定的实现,如果你想访问特定于List&lt;的方法。串GT;例如.ForEach(),您需要将其转换为List:

((List<string>)Strings).ForEach(Console.WriteLine);

但这对于可迁移性来说是一个很小的代价[就是这个词?]。

答案 1 :(得分:9)

静态构造:

public class Foo
{
    private static readonly ICollection<string> _collection;

    static Foo()
    {
        _collection = new List<string>();
        _collection.Add("One");
        _collection.Add("Two");
    }
}

但请注意,在这种情况下,您只需初始化内联集合(推荐用于performance reasons):

private static readonly ICollection<string> _collection = new List<string>(new string[] { "One", "Two" });

这实际上取决于初始化代码的复杂程度。

答案 2 :(得分:5)

也许您可以调用静态方法:

public class Foo
{
    private static readonly ICollection<string> g_collection = initializeCollection();

    private static ICollection<string> initializeCollection()
    {
        ... TODO allocate and return something here ...
    }
}

或者,有一个静态构造函数(正如其他人建议的那样)可能是等价的,甚至更具惯用性。

答案 3 :(得分:1)

除了静态构造函数之外,这也可以工作

    public class Foo
    {
        private static readonly ICollection<string> _collection = 
              new List<string>(new string[] { "elem1", "elem2", "...", "elemn" });
    }

答案 4 :(得分:0)

我能想到的唯一方法就是拥有一个静态构造函数。首先,你在类级别新建一个新集合,然后在静态构造函数中添加所有值。

答案 5 :(得分:0)

你可以声明一个自定义集合类并将它自己的ctor添加到它......

  public class MyFooCollection: Collection<string>
   {
      public MyFooCollection(string[] values)
      {
          foreach (string s in values)  base.Add(s); 
      }
   }

然后在您的客户端代码中编写

  private static final MyFooCollection g_collection = 
         new MyFooCollection(new string[] {"A", "B"});

答案 6 :(得分:0)

我喜欢使用IEnumerable<T>.ToList() 此外,如果您的收藏品应该是只读的,则可以使用System.Collections.ObjectModel.ReadOnlyCollection

private readonly ICollection<string> collection = new string[] { "a", "b", "c" }.ToList();

private readonly ReadOnlyCollection<string> collection2 = new ReadOnlyCollection<string>(new string[] { "a", "b", "c" });

编辑:
然后,如果您将其用作ICollection,则可以简单地使用数组构造函数(因为T[]IList<T>ICollection<T>)。请记住,在这种情况下,许多更改方法(如Add)将失败:

private readonly ICollection<string> = new string[] { "a", "b", "c" };
编辑#2:编辑#2: 我刚刚意识到ToList是一个扩展函数,只能在C#3.0中使用。您仍然可以使用List构造函数:

private readonly IList<string> = new List<string>(new string[] { "a", "b", "c" });

不过,我更喜欢ReadOnlyCollection只读列表。

答案 7 :(得分:0)

使用静态构造函数,如下所示:

public class Foo
{
    static readonly ICollection<string> g_collection;

    // Static constructor
    static Foo()
    {
        g_collection = new List<string>();
        g_collection.Add("Hello");
        g_collection.Add("World!");
    }
}

答案 8 :(得分:0)

您有两种选择:

  1. 使用静态方法的返回值初始化集合。

  2. 使用静态构造函数创建集合,填充它并将其初始化为静态变量。

  3. 从性能角度看,选项1更好,因为在静态构造函数的情况下,运行时必须检查在每次访问类之前是否调用了静态构造函数。