如何在C#中将接口实现委派给其他类
时间:2020-03-06 14:39:03 来源:igfitidea点击:
假设下面的类:
public class MyEnum: IEnumerator { private List<SomeObject> _myList = new List<SomeObject>(); ... }
有必要在MyEnum中实现IEnumerator方法。
但是是否可以将IEnumerator的实现直接"委派"或者重定向到_myList而不需要实现IEnumerator方法?
解决方案
除非我们从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>接口。
如果要以调用者无法修改集合的方式返回集合,则可能需要将列表包装到ReadOnlyCollection <>中并返回ReadOnlyCollection <>的IEnumerable <>。
这样,我们可以确保收藏集不会更改。
方法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是首选。
除了使用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(); } }
该解决方案是确保调用代码无法修改列表,并且每个枚举器在每种方式上(例如排序)都独立于其他枚举器。
再次感谢。