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

本文关键字:返回 属性 默认 设置 对象 | 更新日期: 2023-09-27 18:31:34

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

我有这样的东西:

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>类检索其"底层数组"相同的方式检索我的数组。

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

如果允许

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>
}

要在 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();
    }
}

我添加了一个简单的 null 检查,以防 List 从未被分配,它在枚举时不会抛出。

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

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

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

责声明

我添加它只是因为 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>实现的接口(和所有方法)方法,而不仅仅是将基础集合公开为副本。

听起来你可能想要创建一个索引器。您可以按如下方式执行此操作:

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];

您可能还需要查看泛型类,这些类在创建自定义容器时很有用。