簡體   English   中英

在C#2.0中初始化非空靜態集合的正確方法是什么?

[英]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. 使用靜態方法的返回值初始化集合。

  2. 使用靜態構造函數創建集合,填充它並將其初始化為靜態變量。

從性能角度來看,選項1更好,因為在靜態構造函數的情況下,運行時必須檢查在每次訪問類之前是否調用了靜態構造函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM