使用从列表中返回项目的调用或列表中的第一项来实现API

时间:2015-10-20 14:42:48

标签: c# collections

我有一个庞大的代码库,它假定字段包含类T的单个值。不幸的是,新客户端要求我们将这些字段指向List(Of T)。我可以更改字段类型,但随后所有旧代码都会中断。

在VB中我会这样解决:

Private theList As List(Of T) = new List(Of T)
Public ReadOnly Property Thing() As T
  Get
     Return theList(0)
  End Get
End Property
Public ReadOnly Property Thing(i As Integer) As T
  Get
     Return theList(i) 'yes, this should throw
  End Get
End Property

这依赖于VB能够具有多个具有相同名称的属性,并且使参数传递和索引的括号重载。但是,C#为后者使用大括号,并且没有与参数化属性相对应的任何内容。相反,他们有“this []”,并且由于该名称是私有的,你不能拥有没有参数的“this”而另一个没有参数(这是真的,对吧?)。

但是我如何在C#中做到这一点?我怀疑我可以用模板做到这一点,但我有点迷失它的样子。我可以想象一个带有this[]的List(Of T)子类,但后来我不确定如何在其他类中实现访问器,这样我仍然有Thing和{{1} }。有一点需要注意,这些对象通常用于VBA,因此需要可以COM导出。

3 个答案:

答案 0 :(得分:2)

如果是getter本身,您可以添加一个方法来访问该属性。 例如:

class Eg
{
    List<T> Test { get; set; }

    T GetTest()
    {
        return Test[0];
    }

    T GetTest(int index)
    {
        return Test[index];
    }
}

然后您将像这样访问该属性(如果需要,您可以删除getter):

Eg eg = new Eg();
T t = eg.GetTest();

T t = eg.GetTest(i);

答案 1 :(得分:1)

我建议使用Linq库中的FirstOrDefault,因为List [0]会在空列表中出错而且还意味着您无法切换到不支持索引读取的任何其他数据类型

private List<T> items = new List<T>();

public T Item
{
    get { return items.FirstOrDefault(); }
}

public List<T> Items
{
    get { return items; }
}

但是属性不接受参数化,除非以此属性的形式

如果您使用了一种方法,那么它将起作用,例如

public T GetData()
{
    get { return items.FirstOrDrfault(); }
}

public T GetData(int index)
{
    get { return items[index]; }
}

答案 2 :(得分:0)

如果您需要让您的类为新客户端提供功能,您可能需要更改设计以使它们依赖于接口,而不是类的特定实现。

那就是说,如果你的新客户端听起来需要一个不同的类,可能包含旧类的集合,而不是改变你的类以适应新的客户端。