在C#中公开数组元素的属性

时间:2010-08-23 12:59:50

标签: c# arrays properties

我想在C#中创建一个属性,用于设置或返回数组的单个成员。目前,我有这个:

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

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

但是,我得到以下编译错误:

  

错误数组声明符:要声明托管数组,等级说明符在变量的标识符之前。要声明固定大小的缓冲区字段,请在字段类型之前使用fixed关键字。

10 个答案:

答案 0 :(得分:14)

这个怎么样:编写一个只做一件事和一件事的类:提供对某些底层索引集合的元素的随机访问。将类命名为this索引器。

对于要提供随机访问权限的属性,只需返回此索引器类的实例。

琐碎的实施:

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>接口公开这些属性。

答案 1 :(得分:5)

您必须使用this作为索引器的属性名称。

答案 2 :(得分:5)

C#每个类只允许一个索引属性,因此您不得不使用它。

答案 3 :(得分:2)

你可以这样使用它:

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

        set
        {
            myProp = value;
        }
    }

并且可以访问我的Prop [1]作为例子的支柱[1]

答案 4 :(得分:2)

通过只读属性公开您的阵列可能会满足您的需求。由于您不希望允许其他代码分配数组,因此不需要公共setter:

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

答案 5 :(得分:1)

选项是按如下方式重新编码:

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

它会编译,但它确实有自己的问题(fxCop会对它大喊大叫,但它可以引导你到其他选项)。

答案 6 :(得分: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];
    }
}

答案 7 :(得分: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
    }
}

答案 8 :(得分:1)

C#没有提供内置机制来创建索引属性。您可以使用类级索引器(使用this[int index]表示法),但在属性级别上没有这样的内容。

一种选择是使用索引器创建一个辅助类,并使用此类作为属性类型。在MSDN上查看example

答案 9 :(得分: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...