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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/413700/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:28:32  来源:igfitidea点击:

What is the right way to initialize a non-empty static collection in C# 2.0?

c#collections

提问by Aaron Whittier

I want to initialize a static collection within my C# class - something like this:

我想在我的 C# 类中初始化一个静态集合 - 像这样:

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

I'm not sure of the right way to do this; in Java I might do something like:

我不确定这样做的正确方法;在 Java 中,我可能会执行以下操作:

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

is there a similar construct in C# 2.0?

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

I know in later versions of C#/.NET you can do collection initializers (http://msdn.microsoft.com/en-us/library/bb384062.aspx), but migration isn't an option for our system at the moment.

我知道在更高版本的 C#/.NET 中你可以做集合初始值设定项(http://msdn.microsoft.com/en-us/library/bb384062.aspx),但目前我们的系统不支持迁移.

To clarify my original question - I'm looking for a way to succinctly declare a simple static collection, such as a simple constant collection of strings. The static-initializer-style way is also really good to know for collections of more complex objects.

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

Thanks!

谢谢!

采纳答案by BenAlabaster

If I fully understand your question, it seems some others have missed the point, you're looking to create a static collection in a similar manner to Java in that you can declare and populate in a single line of code without having to create a dedicated method to do this (as per some of the other suggestions). This can be done using an array literal (written over two lines to prevent scrolling):

如果我完全理解您的问题,似乎其他一些人没有抓住重点,您希望以类似于 Java 的方式创建静态集合,因为您可以在一行代码中声明和填充,而无需创建专用方法来做到这一点(根据其他一些建议)。这可以使用数组文字来完成(写在两行上以防止滚动):

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

This both declares and populates the new readonly collection with the item list in one go. Works in 2.0 and 3.5, I tested it just to be doubly sure.

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

In 3.5 though you can use type inference so you no longer need to use the string[] array which removes even more keystrokes:

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

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

Notice the missing "string" type in the second line line. String is automatically inferred from the contents of the array initializer.

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

If you want to populate it as a list, just change up the new string[] for new List a la:

如果要将其填充为列表,只需将 new string[] 更改为 new List a la:

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

Of course, because your type is IEnumerable rather than a specific implementation, if you want to access methods specific to List< string> such as .ForEach(), you will need to convert it to List:

当然,因为你的类型是IEnumerable而不是具体的实现,如果你想访问List<string>特有的方法,比如.ForEach(),你需要把它转换成List:

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

But it's a small price to pay for migratability [is that a word?].

但为可迁移性付出的代价很小[是一个词吗?]。

回答by ChrisW

Perhaps you can call a static method:

也许你可以调用一个静态方法:

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

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

Or, having a static constructor (as other people suggested) might be equivalent, or even more idiomatic.

或者,拥有一个静态构造函数(正如其他人所建议的)可能是等效的,甚至更符合习惯。

回答by BFree

The only way I can think of would be to have a static constructor. So first you new up a new collection at the class level, then in your static constructor, add all the values to it.

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

回答by Charles Bretana

you could declare a custom collection class and add your own ctor to it...

您可以声明一个自定义集合类并将您自己的构造函数添加到其中...

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

then in your client code you could write

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

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

回答by Kent Boogaart

Static construction:

静态构造:

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

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

But note that in this case you can just initialize the collection inline (recommended for performance reasons):

但请注意,在这种情况下,您可以内联初始化集合(出于性能原因推荐):

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

It really depends on how complex your initialization code is.

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

回答by configurator

I like using IEnumerable<T>.ToList().
Also, if your collection should be readonly, you can use a System.Collections.ObjectModel.ReadOnlyCollection.

我喜欢使用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" });

EDIT:
Then again, if you're using it as an ICollection, you can simply use the array constructor (since T[]is an IList<T>and an ICollection<T>). Keep in mind that in this case many alterring methods such as Add would fail:

编辑:
再说一次,如果您将它用作 ICollection,则可以简单地使用数组构造函数(因为T[]是 anIList<T>和 an ICollection<T>)。请记住,在这种情况下,许多更改方法(例如 Add)都会失败:

private readonly ICollection<string> = new string[] { "a", "b", "c" };

EDIT #2: I just realized ToList is an extention function and can only be used in C# 3.0. You can still use the List constructor though:

编辑 #2:我刚刚意识到 ToList 是一个扩展函数,只能在 C# 3.0 中使用。您仍然可以使用 List 构造函数:

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

Still, I prefer ReadOnlyCollectionfor read only lists.

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

回答by Juliet

Use a static constructor as follows:

使用静态构造函数如下:

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!");
    }
}

回答by Pablo Retyk

besides of static constructor, this also will work

除了静态构造函数,这也将起作用

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

回答by vboctor

You have two options:

您有两个选择:

  1. Use the return value of a static method to initialize the collection.

  2. Use a static constructor to create the collection, populate it and initialize it to the static variable.

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

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

From a performance perspective option 1 is better, since in the case of static constructors, the runtime has to check if the static constructor was called before every access to the class.

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