假设下面的类:如何委托接口实现与其他类在C#
public class MyEnum: IEnumerator
{
private List<SomeObject> _myList = new List<SomeObject>();
...
}
有必要实施MyEnum的IEnumerator的方法。 但是是否可以将IEnumerator的实现直接委托给_myList而无需实现IEnumerator方法?
假设下面的类:如何委托接口实现与其他类在C#
public class MyEnum: IEnumerator
{
private List<SomeObject> _myList = new List<SomeObject>();
...
}
有必要实施MyEnum的IEnumerator的方法。 但是是否可以将IEnumerator的实现直接委托给_myList而无需实现IEnumerator方法?
方法1: 继续使用封装和转发调用到List实现。
class SomeObject
{
}
class MyEnum : IEnumerable<SomeObject>
{
private List<SomeObject> _myList = new List<SomeObject>();
public void Add(SomeObject o)
{
_myList.Add(o);
}
public IEnumerator<SomeObject> GetEnumerator()
{
return _myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
class Program
{
static void Main(string[] args)
{
MyEnum a = new MyEnum();
a.Add(new SomeObject());
foreach (SomeObject o in a)
{
Console.WriteLine(o.GetType().ToString());
}
Console.ReadLine();
}
}
方法2: 继承List实现你这种行为是免费的。
class SomeObject
{
}
class MyEnum : List<SomeObject>
{
}
class Program
{
static void Main(string[] args)
{
MyEnum a = new MyEnum();
a.Add(new SomeObject());
foreach (SomeObject o in a)
{
Console.WriteLine(o.GetType().ToString());
}
Console.ReadLine();
}
}
方法1可以更好的沙箱,因为没有方法将在列表被称为无MyEnum知识。费力最少方法2是优选的。
不除非你从List < T>派生。
public class MyEnum : List<SomeObject>, IEnumerable<SomeObject>{}
你可以这样做:
public class MyEnum : IEnumerator {
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator GetEnumerator() { return this._myList.GetEnumerator(); }
}
原因很简单。你的类可以包含几个属于集合的字段,所以编译器/环境无法知道应该使用哪个字段来实现“IEnumerator”。
EIDT:我同意@pb - 你应该实现IEnumerator <SomeObject>接口。
要实现的接口是IEnumerable而不是IEnumerator。 – 2008-09-24 09:28:39
如果你想要的方式返回一个集合,其中来电者是无法修改集合,你可能希望将列表包装成一个ReadOnlyCollection <>和ReadOnlyCollection <的返回IEnumerable的<>>。
这样你可以确定你的收藏将不会改变。
除了使用pb的方法,这是不可能的一个“简单”的原因:接口方法需要通过this
指针作为第一个参数。当您在对象上调用GetEnumerator
时,此指针将成为您的对象。但是,为了使调用在嵌套列表上工作,指针必须是对该列表的引用,而不是您的类。
因此,您明确地必须将方法委托给其他对象。
(顺便提一句,在其他答复意见是正确的:使用IEnumerator<T>
,不IEnumerable
!)
感谢大家的输入和解释。 最后,我已经联合一些你的答案以下几点:
class MyEnum : IEnumerable<SomeObject>
{
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator<SomeObject> GetEnumerator()
{
// Create a read-only copy of the list.
ReadOnlyCollection<CustomDevice> items = new ReadOnlyCollection<CustomDevice>(_myList);
return items.GetEnumerator();
}
}
该解决方案是确保调用的代码是不能修改的列表,每个枚举是别人的独立的以各种方式(例如使用排序) 。 再次感谢。
您可以通过`ReadOnlyCollection`传递,因为`IEnumerable`永远不可改变!用户必须上传并猜测列表的原始类型才能对其进行修改。复制列表恕我直言,不是一个好主意。 – 2008-09-24 14:22:23
指出,由于duck-typing,可以具有GetEnumerator
方法的对象上使用foreach
- 对象类型不必实际执行IEnumerable
。
所以,如果你这样做:
class SomeObject
{
}
class MyEnum
{
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator<SomeObject> GetEnumerator()
{
return _myList.GetEnumerator();
}
}
那么这工作得很好:
MyEnum objects = new MyEnum();
// ... add some objects
foreach (SomeObject obj in objects)
{
Console.WriteLine(obj.ToString());
}
我意识到这不是对原始问题的一般回答,但它与问题中提供的特定用例有关。 – yoyo 2017-06-07 20:43:02
好吧,这将工作,但我想肯定的是,调用代码是不能型铸造枚举器再次列出并添加或删除对象。 – Willem 2008-09-24 09:23:46