2010-08-23 46 views
11

我想在C#中創建一個設置或返回數組的單個成員的屬性。目前,我有這樣的:在C中暴露數組元素的屬性#

private string[] myProperty; 
public string MyProperty[int idx] 
{ 
    get 
    { 
     if (myProperty == null) 
      myProperty = new String[2]; 

     return myProperty[idx]; 
    } 
    set 
    { 
     myProperty[idx] = value; 
    } 
} 

不過,我得到以下編譯錯誤:

Bad array declarator: To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type.

+0

http://www.codeproject.com/KB/cs/csharptips.aspx – 2010-08-23 13:11:15

回答

12

這個怎麼樣:編寫一個只做一件事和一件事的類:提供對某些基礎索引集合的元素的隨機訪問。給這個 class a this indexer。

對於要提供隨機訪問的屬性,只需返回此索引器類的實例即可。

簡單的實現:

public class Indexer<T> 
{ 
    private IList<T> _source; 

    public Indexer(IList<T> source) 
    { 
     _source = source; 
    } 

    public T this[int index] 
    { 
     get { return _source[index]; } 
     set { _source[index] = value; } 
    } 
} 

public static class IndexHelper 
{ 
    public static Indexer<T> GetIndexer<T>(this IList<T> indexedCollection) 
    { 
     // could cache this result for a performance improvement, 
     // if appropriate 
     return new Indexer<T>(indexedCollection); 
    } 
} 

重構到你的代碼:

private string[] myProperty; 
public Indexer<string> MyProperty 
{ 
    get 
    { 
     return myProperty.GetIndexer(); 
    } 
} 

這將讓你有儘可能多的索引屬性,只要你想,無需暴露與IList<T>接口的性能。

5

必須使用this作爲索引的屬性名稱。

+0

如果我有多個? – 2010-08-23 13:03:24

+0

您必須讓MyProperty返回某種可索引列表。如果您需要嚴格控制,您可能需要自己實施。 – recursive 2010-08-23 13:08:42

0

您需要使用索引器。它有點不同。請參閱示例:

public class Node 
{ 
    public Node this[int offset] 
    { 
     get { return localList[offset]; } 
    } 
} 

注意:每個類只允許一個索引器。原因在於它對於編譯器來說太含糊不清了,所以你只允許一個。

你也可以這樣做:

private static int[] _widget = new int[Counter]; 
public static int [] Widget 
{ 
    get { return _widget; } 
    set { _widget = value; } 
} 

...

for (int i = 0; i < MyClass.Counter; i++) 
{ 
    MyClass.Widget[i] = i; 
} 

... 
double _newWidget5 = MyClass.Widget[5]; 
// and so on... 
5

C#允許每個班只有一個索引屬性,所以你不得不使用這一點。

+0

這是不正確的。只要簽名不同,就可以有多個索引器,即用作索引值的類型是不同的。 – 2010-08-23 13:38:41

+0

那時事情已經改變了。最初這種限制確實存在。你介意發佈新的語法,並告訴我們何時添加到語言? – joekoyote 2010-08-23 14:05:33

+0

也許我們正在交叉討論:你可以在public int this [int index]這邊聲明'public int this [string index]',它們可以做兩個完全不同的事情。我會說這是一個以上的索引財產。 – 2010-08-23 14:11:53

1

的選項如下重新編寫它:

private string[] myProperty = new string[2]; 
public string[] MyProperty 
{ 
    get 
    { 
     return myProperty; 
    } 
    set 
    { 
     myProperty = value; 
    } 
} 

它會編譯,但它確實有它自己的一套問題(的FxCop會吆喝它,但它可能會導致你到其他選項) 。

+0

這比原始接口更強大,它只允許修改元素。這實際上允許通過set替換底層數組。 – 2010-08-23 13:26:25

1

你可以做這樣的事情:

class Indexers 
{ 
    private string[] _strings = new [] {"A","B"}; 
    private int[] _ints = new[] { 1, 2 }; 

    public string[] Strings 
    { 
     get{ return _strings;} 
    } 

    public int[] Ints 
    { 
     get{ return _ints;} 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Indexers indexers = new Indexers(); 

     int a1 = indexers.Ints[0]; 
     string a2 = indexers.Strings[0]; 
    } 
} 
2

你可以用這種方式:

private string[] myProp; 
    public string[] MyProp 
    { 
     get 
     { 
      if (myProp == null) 
      { 
       myProp = new String[2]; 
      } 
      return myProp; 
     } 

     set 
     { 
      myProp = value; 
     } 
    } 

並有可能進入電影myProp [1] MyProp [1]例如

2

通過只讀屬性公開數組可能會滿足您的需求。既然你不想讓其他代碼數組作爲這樣的分配,也沒有必要爲公衆制定者:

private string[] myProperty; 
public string[] MyProperty 
{ 
    get 
    { 
     if (myProperty == null) 
     { 
      myProperty = new String[2]; 
     } 

     return myProperty; 
    } 
} 

然後,你可以寫代碼這樣:

theObject.MyProperty[1] = "some string"; 

.. 。但你不能代替數組本身:

theObject.MyProperty = new string[2]; // will not compile 
1

首先,在現場聲明可以避免多餘的檢查:

private string[] myProperty = new string[2]; 

您可以通過按輸入型重載實現多個索引:

public string this[int index] 
{ 
    get 
    { 
     return myProperty[index]; 
    } 
    set 
    { 
     myProperty[index] = value; 
    } 
} 

public object this[object a, object b] // different input type(s) (and different return type) 
{ 
    get 
    { 
     // do other stuff 
    } 
} 
1

C#不提供內置的機制來創建索引屬性。您可以使用類級別的索引器(使用this[int index]表示法),但在屬性級別上不會出現這種情況。

一種方法是使用索引器創建一個輔助類,並將此類用作屬性類型。請參閱MSDN上的example