C# 如何在C中将接口实现委托给其他类#

C# 如何在C中将接口实现委托给其他类#,c#,interface,C#,Interface,假设以下类别: public class MyEnum: IEnumerator { private List<SomeObject> _myList = new List<SomeObject>(); ... } 公共类MyEnum:IEnumerator { 私有列表_myList=新列表(); ... } 有必要在MyEnum中实现IEnumerator方法。 但是,是否可以直接将IEnumerator的实现“委托”或重定向到_myList,而无需实现I

假设以下类别:

public class MyEnum: IEnumerator
{
    private List<SomeObject> _myList = new List<SomeObject>();
...
}
公共类MyEnum:IEnumerator
{
私有列表_myList=新列表();
...
}
有必要在MyEnum中实现IEnumerator方法。
但是,是否可以直接将IEnumerator的实现“委托”或重定向到_myList,而无需实现IEnumerator方法?

除非您从列表派生

公共类MyEnum:List,IEnumerable{}
您可以执行以下操作:

public class MyEnum : IEnumerator {
    private List<SomeObject> _myList = new List<SomeObject>();
    public IEnumerator GetEnumerator() { return this._myList.GetEnumerator(); }
}
公共类MyEnum:IEnumerator{
私有列表_myList=新列表();
public IEnumerator GetEnumerator(){返回此值。_myList.GetEnumerator();}
}
原因很简单。您的类可以包含几个属于集合的字段,因此编译器/环境无法知道应该使用哪个字段来实现“IEnumerator”


EIDT:我同意@pb-您应该实现IEnumerator接口。

如果您希望以调用方无法修改集合的方式返回集合,您可能希望将列表包装到ReadOnlyCollection中,并返回ReadOnlyCollection的IEnumerable

这样您就可以确保您的收藏不会被更改。

方法1: 继续使用封装并将调用转发到列表实现

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();
    }
}
class-SomeObject
{
}
MyEnum类:IEnumerable
{
私有列表_myList=新列表();
公共void添加(SomeObject o)
{
_添加(o);
}
公共IEnumerator GetEnumerator()
{
返回_myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回此.GetEnumerator();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
MyEnum a=新的MyEnum();
a、 添加(newsomeobject());
foreach(a中的某个对象o)
{
WriteLine(o.GetType().ToString());
}
Console.ReadLine();
}
}
方法2: 从列表实现继承您可以免费获得该行为

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();
    }
}
class-SomeObject
{
}
MyEnum类:列表
{
}
班级计划
{
静态void Main(字符串[]参数)
{
MyEnum a=新的MyEnum();
a、 添加(newsomeobject());
foreach(a中的某个对象o)
{
WriteLine(o.GetType().ToString());
}
Console.ReadLine();
}
}

方法1允许更好的沙箱处理,因为在没有MyEnum知识的情况下,列表中不会调用任何方法。为了省力起见,首选方法2。

除了使用pb的方法外,由于一个“简单”的原因,这是不可能的:接口方法需要传递一个
this
指针作为第一个参数。在对象上调用
GetEnumerator
时,此指针将是您的对象。但是,为了使调用在嵌套列表上工作,指针必须是对该列表的引用,而不是您的类

因此,您必须显式地将该方法委托给另一个对象


(顺便说一句,另一个回复中的建议是正确的:使用
IEnumerator
,而不是
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();
    }
}
class MyEnum:IEnumerable
{
私有列表_myList=新列表();
公共IEnumerator GetEnumerator()
{
//创建列表的只读副本。
ReadOnlyCollection项=新的ReadOnlyCollection(\u myList);
返回项。GetEnumerator();
}
}
此解决方案旨在确保调用代码无法修改列表,并且每个枚举数在各个方面都独立于其他枚举数(例如,排序)。 再次感谢。

请注意,由于,您可以在任何具有
GetEnumerator
方法的对象上使用
foreach
——对象类型实际上不需要实现
IEnumerable

因此,如果您这样做:

class SomeObject
{
}

 class MyEnum
 {
    private List<SomeObject> _myList = new List<SomeObject>();

    public IEnumerator<SomeObject> GetEnumerator()
    {
        return _myList.GetEnumerator();
    }
 }

好的,这将起作用,但我想确保调用代码不能再次键入强制转换枚举数以列出并从中添加或删除对象。要实现的接口是IEnumerable而不是IEnumerator。您可以通过
ReadOnlyCollection
,因为
IEnumerable
无论如何都是不可变的!用户必须向上转换并猜测列表的原始类型才能修改它。复制列表不是一个好主意。我意识到这不是对原始问题的一般回答,但它与问题中提供的特定用例相关。如果你意识到你没有回答问题,那么不要发布问题的答案。答案是为了回答问题,而不是发布你觉得有趣的随机琐碎事实。在这种情况下,这实际上并没有帮助你;在这种情况下,没有理由不实际实现接口。问题是如何委托接口的实现,以避免编写样板代码。我的回答是授权实现IEnumerable的常见案例的潜在答案,这也恰好是OP使用的示例。我讨论了是将其作为评论还是答案,并决定将其作为答案。这是对问题的一种特定形式的回答,但是你在整个回答中都在谈论如何不需要实际实现接口,在这种情况下,这是不必要的,甚至是没有帮助或可取的。你只是在解释一个离题的、没有帮助的、切题的问题,而不是实际回答问题。这使得它不是一个答案(甚至不是一个有用的评论)。请重新阅读原始问题的主体:“是否可以在不需要实现IEnumerator方法的情况下将IEnumerator的实现直接“委托”或重定向到_myList?”-我的回答相当直接地解决了这一问题。肯定b
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());
}