在 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
What is the right way to initialize a non-empty static collection in C# 2.0?
提问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 ReadOnlyCollection
for 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:
您有两个选择:
Use the return value of a static method to initialize the collection.
Use a static constructor to create the collection, populate it and initialize it to the static variable.
使用静态方法的返回值来初始化集合。
使用静态构造函数创建集合,填充它并将其初始化为静态变量。
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 更好,因为在静态构造函数的情况下,运行时必须在每次访问类之前检查是否调用了静态构造函数。