假设以下课程:
public class MyEnum: IEnumerator
{
private List<SomeObject> _myList = new List<SomeObject>();
...
}
有必要在MyEnum中实现IEnumerator方法。 但是,是否可以将IEnumerator的实现直接“委托”或重定向到_myList而无需实现IEnumerator方法?
答案 0 :(得分:7)
方法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知识的情况下,没有方法可以在List中调用。最少努力方法2 是首选。
答案 1 :(得分:1)
你可以这样做:
public class MyEnum : IEnumerator {
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator GetEnumerator() { return this._myList.GetEnumerator(); }
}
原因很简单。您的类可以包含多个集合字段,因此编译器/环境无法知道应该使用哪个字段来实现“IEnumerator”。
EIDT:我同意@pb - 你应该实现IEnumerator&lt; SomeObject&gt;接口
答案 2 :(得分:1)
除了使用pb的方法之外,由于“简单”的原因,这是不可能的:接口方法需要传递this
指针作为第一个参数。当您在对象上调用GetEnumerator
时,此指针将成为您的对象。但是,为了使调用在嵌套列表上工作,指针必须是对该列表的引用,而不是您的类。
因此,您必须明确地将该方法委托给另一个对象。
(顺便说一句,其他回复中的建议是正确的:使用IEnumerator<T>
,不 IEnumerable
!)
答案 3 :(得分:0)
如果要以调用者无法修改集合的方式返回集合,您可能希望将List包装到ReadOnlyCollection&lt;&gt;中。并返回IEnumerable&lt;&gt; ReadOnlyCollection&lt;&gt;。
通过这种方式,您可以确保不会更改您的收藏。
答案 4 :(得分:-1)
除非您从List&lt; T&gt;派生。
public class MyEnum : List<SomeObject>, IEnumerable<SomeObject>{}
答案 5 :(得分:-1)
谢谢大家的意见和解释。 最后,我将您的一些答案与以下内容结合起来:
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();
}
}
此解决方案是确保调用代码无法修改列表,并且每个枚举器在各方面都与其他枚举器无关(例如,使用排序)。 再次感谢。
答案 6 :(得分:-1)
请注意,感谢duck-typing,您可以对任何具有routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Welcome", action = "Index", id = UrlParameter.Optional }
);
方法的对象使用foreach
- 对象类型无需实际实现GetEnumerator
。
所以,如果你这样做:
IEnumerable
然后这很好用:
class SomeObject
{
}
class MyEnum
{
private List<SomeObject> _myList = new List<SomeObject>();
public IEnumerator<SomeObject> GetEnumerator()
{
return _myList.GetEnumerator();
}
}