如何在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();
}
}
该解决方案是确保调用代码无法修改列表,并且每个枚举器在每种方式上(例如排序)都独立于其他枚举器。
再次感谢。

