我试图实现自己的列表类。只是为了培训,更好地了解事情是如何运作的。
我有类似的东西:
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)
我希望能够像.NET
或C#
List<T>
类检索它的基础数组&#34;一样检索我的数组。
答案 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];
您可能还想查看在创建自定义容器时非常有用的泛型类。