如何为对象/类默认设置要返回的类的属性?

时间:2016-01-22 21:11:42

标签: c#

我试图实现自己的列表类。只是为了培训,更好地了解事情是如何运作的。

我有类似的东西:

public class TestClass {
    public int[] List;
    // Add(), ...
}

我希望能够像这样检索数组(这是TestClass的属性):

var testClass = new TestClass();
int[] list = testClass; // without the ".List" list would point to the array

而不是这样:

var testClass = new TestClass();
int[] list = testClass.List;

与c#内置泛型列表类的使用方式相同。

我如何实现这一目标(如果可能的话)?

更新

我更改了"列表"到int[],我希望这会有所帮助。

我知道我可以做类似的事情:

int[] list = new int[10];

但我需要TestClass,因为我需要一些关于数组的其他(扩展)属性以及更多自定义方法。

更新2

也许这会让事情变得更清楚。

我试图找出通用List<T>类在这种情况下的工作原理:

var list = new List<T>();
foreach(var oneElement in list)

就我而言,我必须这样做:

var list = new TestClass();
foreach(var oneElement in list.List)

我希望能够像.NETC# List<T>类检索它的基础数组&#34;一样检索我的数组。

4 个答案:

答案 0 :(得分:3)

如果var list允许使用其中一种IEnumerable<T>ICollection<T>IList<T>,那么您只需要实现其中一个接口IEnumerable<T>ICollection<T>IList<T>

public class TestClass : IList<SomeTypeOrGenericT>
{
    public SomeTypeOrGenericT[] List;
    // ...

    // members of IList<SomeTypeOrGenericT>
}

答案 1 :(得分:1)

要在foreach语句中使用您的类,您应该实现IEnumerable<T>。这非常简单:

public class TestClass : IEnumerable<int>
{
    private static readonly int[] Empty = new int[0];

    public int[] List;

    public IEnumerator<int> GetEnumerator() 
    {
        int[] array = List == null ? Empty : List;
        return array.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerator.GetEnumerator()
    {
        return GetEnumerator();
    }
}

我添加了一个简单的空检查,以防List永远不会被赋值,它在枚举时不会抛出。

这允许您在foreach语句中使用它,以及使用LINQ扩展方法:

var list = new TestClass();
foreach(var oneElement in list)
{
}

如果您想要其他列表功能,您应该实现IList<T>。还有一个基类System.Collections.ObjectModel.Collection<T>可以为您实现所有这些功能。它具有可覆盖的方法,因此您可以在添加或删除项目时更新类中的其他状态。 List<T>没有可覆盖的方法,因此它作为基类的用途是有限的。

答案 2 :(得分:0)

<强>声明

我之所以添加这个只是因为OP要求它,但我不认为这是这个(或大多数其他)情况下的合适解决方案。

  

我希望能够得到这样的列表:

var testClass = new TestClass();
var list = testClass;

一个问题是你正在使用var。编译器将使用list的最合理的类型,即TestClass,因为这是testClass的类型。

如果您希望list属于列表类型,可以添加隐式转换运算符

public class TestClass<T> {
    public T[] List ;
    // ...

    public static implicit operator List<T>(TestClass<T> t)
    {
       return t.List.ToList();
    }
}

但是你必须指定list的类型,以便编译器知道如何转换对象:

var testClass = new TestClass<int>();
testClass.List = new[] {1,2,3,4};
List<int> list = testClass; // can't use `var here AND cast to List<T>

另请注意,“列表”是只读的。您正在检索内部列表的副本。我怀疑你想要实现List<T>实现的接口(和所有方法)方法,而不是将底层集合作为副本公开。

答案 3 :(得分:-1)

听起来你可能想要创建一个索引器。你可以这样做:

public class TestClass
{
    public object this[int i]
    {
        get
        {
            // put your code here to return object i from the list
        }
        set
        {
            // put your code here to set object i in the list.
            // A variable named "value" contains the incoming value.
        }
    }
}

您现在可以按如下方式访问列表中的项目:

var testClass = new TestClass();
testClass[0] = 100; // any object really
var item = testClass[0];

您可能还想查看在创建自定义容器时非常有用的泛型类。