[英]What is the right way to initialize a non-empty static collection in C# 2.0?
我想在我的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 ),但目前我們的系統不能選擇遷移。
澄清我原來的問題 - 我正在尋找一種方法來簡潔地聲明一個簡單的靜態集合,例如一個簡單的常量字符串集合。 對於更復雜的對象的集合,靜態初始化器方式也非常好。
謝謝!
如果我完全理解你的問題,似乎有些人忽略了這一點,你正在尋找以類似於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 <string>的方法,比如.ForEach(),你需要將它轉換為List:
((List<string>)Strings).ForEach(Console.WriteLine);
但這對於可遷移性來說是一個很小的代價[就是這個詞?]。
靜態結構:
public class Foo
{
private static readonly ICollection<string> _collection;
static Foo()
{
_collection = new List<string>();
_collection.Add("One");
_collection.Add("Two");
}
}
但請注意,在這種情況下,您只需初始化內聯集合(建議出於性能原因 ):
private static readonly ICollection<string> _collection = new List<string>(new string[] { "One", "Two" });
這實際上取決於初始化代碼的復雜程度。
也許你可以調用靜態方法:
public class Foo
{
private static readonly ICollection<string> g_collection = initializeCollection();
private static ICollection<string> initializeCollection()
{
... TODO allocate and return something here ...
}
}
或者,擁有一個靜態構造函數(正如其他人建議的那樣)可能是等效的,甚至更具慣用性。
除了靜態構造函數,這也將起作用
public class Foo
{
private static readonly ICollection<string> _collection =
new List<string>(new string[] { "elem1", "elem2", "...", "elemn" });
}
我能想到的唯一方法就是擁有一個靜態構造函數。 首先,在類級別創建一個新集合,然后在靜態構造函數中,將所有值添加到它。
你可以聲明一個自定義集合類並添加你自己的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"});
我喜歡使用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:我剛剛意識到ToList是一個擴展函數,只能在C#3.0中使用。 您仍然可以使用List構造函數:
private readonly IList<string> = new List<string>(new string[] { "a", "b", "c" });
不過,我更喜歡ReadOnlyCollection
用於只讀列表。
使用靜態構造函數如下:
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!");
}
}
您有兩種選擇:
使用靜態方法的返回值初始化集合。
使用靜態構造函數創建集合,填充它並將其初始化為靜態變量。
從性能角度來看,選項1更好,因為在靜態構造函數的情況下,運行時必須檢查在每次訪問類之前是否調用了靜態構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.