Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何实现IEnumerable<;T>;_C#_.net_Generics - Fatal编程技术网

C# 如何实现IEnumerable<;T>;

C# 如何实现IEnumerable<;T>;,c#,.net,generics,C#,.net,Generics,我知道如何实现非泛型IEnumerable,如下所示: using System; using System.Collections; namespace ConsoleApplication33 { class Program { static void Main(string[] args) { MyObjects myObjects = new MyObjects(); myObjects[0

我知道如何实现非泛型IEnumerable,如下所示:

using System;
using System.Collections;

namespace ConsoleApplication33
{
    class Program
    {
        static void Main(string[] args)
        {
            MyObjects myObjects = new MyObjects();
            myObjects[0] = new MyObject() { Foo = "Hello", Bar = 1 };
            myObjects[1] = new MyObject() { Foo = "World", Bar = 2 };

            foreach (MyObject x in myObjects)
            {
                Console.WriteLine(x.Foo);
                Console.WriteLine(x.Bar);
            }

            Console.ReadLine();
        }
    }

    class MyObject
    {
        public string Foo { get; set; }
        public int Bar { get; set; }
    }

    class MyObjects : IEnumerable
    {
        ArrayList mylist = new ArrayList();

        public MyObject this[int index]
        {
            get { return (MyObject)mylist[index]; }
            set { mylist.Insert(index, value); }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return mylist.GetEnumerator();
        }
    }
}
然而,我也注意到IEnumerable有一个通用版本,
IEnumerable
,但我不知道如何实现它

如果我使用System.Collections.Generic添加
到我的使用指令,然后更改:

class MyObjects : IEnumerable
致:


GetEnumerator()返回非泛型IEnumerable对象方法这次不起作用,所以我在这里放什么?CLI现在会忽略非泛型实现,并在foreach循环期间尝试枚举my array时直接使用泛型版本。

为什么要手动执行此操作?自动化处理迭代器的整个过程。(我也写过,包括编译器生成的代码)


如果你真的想自己做,你也必须返回一个通用的枚举器。您将无法再使用
ArrayList
,因为这是非泛型的。将其改为
列表
。当然,这假定您的集合中只有类型为
MyObject
(或派生类型)的对象。

将mylist设置为
列表
,这是一个选项

您可能不希望显式实现
IEnumerable
(这就是您所展示的)

通常的模式是在
IEnumerable
的显式实现中使用
IEnumerable
GetEnumerator

class FooCollection : IEnumerable<Foo>, IEnumerable
{
    SomeCollection<Foo> foos;

    // Explicit for IEnumerable because weakly typed collections are Bad
    System.Collections.IEnumerator IEnumerable.GetEnumerator()
    {
        // uses the strongly typed IEnumerable<T> implementation
        return this.GetEnumerator();
    }

    // Normal implementation for IEnumerable<T>
    IEnumerator<Foo> GetEnumerator()
    {
        foreach (Foo foo in this.foos)
        {
            yield return foo;
            //nb: if SomeCollection is not strongly-typed use a cast:
            // yield return (Foo)foo;
            // Or better yet, switch to an internal collection which is
            // strongly-typed. Such as List<T> or T[], your choice.
        }

        // or, as pointed out: return this.foos.GetEnumerator();
    }
}
class FooCollection:IEnumerable,IEnumerable
{
一些收集食物;
//IEnumerable的显式,因为弱类型集合不好
System.Collections.IEnumerator IEnumerable.GetEnumerator()
{
//使用强类型IEnumerable实现
返回此.GetEnumerator();
}
//IEnumerable的正常实现
IEnumerator GetEnumerator()
{
foreach(这个.foos中的Foo-Foo)
{
收益率;
//注意:如果SomeCollection不是强类型的,请使用强制转换:
//收益回报率(Foo)Foo;
//或者更好的是,切换到一个内部集合
//强类型。如列表或T[],由您选择。
}
//或者,正如前面指出的:返回这个.foos.GetEnumerator();
}
}

如果使用泛型,请使用列表而不是ArrayList。该列表正好具有所需的GetEnumerator方法

List<MyObject> myList = new List<MyObject>();
List myList=new List();

如果您选择使用泛型集合,例如
列表
而不是
数组列表
,您会发现
列表
将提供您可以使用的泛型和非泛型枚举数

using System.Collections;

class MyObjects : IEnumerable<MyObject>
{
    List<MyObject> mylist = new List<MyObject>();

    public MyObject this[int index]  
    {  
        get { return mylist[index]; }  
        set { mylist.Insert(index, value); }  
    } 

    public IEnumerator<MyObject> GetEnumerator()
    {
        return mylist.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}
使用系统集合;
MyObject类:IEnumerable
{
List mylist=新列表();
公共MyObject此[int索引]
{  
获取{return mylist[index];}
集合{mylist.Insert(索引,值);}
} 
公共IEnumerator GetEnumerator()
{
返回mylist.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回此.GetEnumerator();
}
}

请注意,
IEnumerable
allready由
System.Collections
实现,因此另一种方法是从
System.Collections
派生
MyObject
类作为基类():

集合:为泛型集合提供基类

稍后,我们可以自行实现覆盖虚拟
System.Collections
方法以提供自定义行为(仅适用于
ClearItems
InsertItem
RemoveItem
SetItem
以及
Equals
GetHashCode
对象中的
ToString
)。不同于
列表
,它的设计不便于扩展

例如:

public class FooCollection : System.Collections<Foo>
{
    //...
    protected override void InsertItem(int index, Foo newItem)
    {
        base.InsertItem(index, newItem);     
        Console.Write("An item was successfully inserted to MyCollection!");
    }
}

public static void Main()
{
    FooCollection fooCollection = new FooCollection();
    fooCollection.Add(new Foo()); //OUTPUT: An item was successfully inserted to FooCollection!
}
公共类FooCollection:System.Collections
{
//...
受保护的重写void插入项(int索引,Foo newItem)
{
base.InsertItem(索引,newItem);
Write(“项目已成功插入MyCollection!”);
}
}
公共静态void Main()
{
FooCollection FooCollection=新建FooCollection();
fooCollection.Add(new Foo());//输出:已成功将项插入fooCollection!
}

请注意,仅当需要自定义收集行为时,才建议从
收集驱动
,这种情况很少发生。请参阅。

+1,应该注意的是,首选模式是实现通用接口并显式实现非通用接口。收益率返回是最自然的解决方案泛型接口。除非OP将在枚举器中进行某些处理,否则使用yield return只会增加另一个状态机的开销。OP应该只返回一个由底层泛型集合提供的枚举器。@MonroeThomas:你说得对。在写
yield ret之前,我没有仔细阅读这个问题urn
。我错误地认为存在一些自定义处理。如果某个集合尚未实现IEnumerable,或者在枚举序列中返回每个元素之前需要对其进行转换或其他处理,则这是一个很好的解决方案。如果这两个条件都不是真的,则在只需返回这个.foos.GetEnumerator();@MonroeThomas:同意。不知道OP使用的是什么集合。这一点很好。但是实现
IEnumerable
是多余的(
IEnumerable
已经继承了它)@rsenna没错,但是请记住,即使是像IList这样的.NET接口也会冗余地实现接口,这是为了可读性-公共接口IList:ICollection,IEnumerable@Backwards_Dave我实际上(仍然)我认为这会降低可读性,因为它会增加不必要的噪音,但我理解你所说的,并且认为这是一个有效的观点
using System.Collections;

class MyObjects : IEnumerable<MyObject>
{
    List<MyObject> mylist = new List<MyObject>();

    public MyObject this[int index]  
    {  
        get { return mylist[index]; }  
        set { mylist.Insert(index, value); }  
    } 

    public IEnumerator<MyObject> GetEnumerator()
    {
        return mylist.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}
public class FooCollection : System.Collections<Foo>
{
    //...
    protected override void InsertItem(int index, Foo newItem)
    {
        base.InsertItem(index, newItem);     
        Console.Write("An item was successfully inserted to MyCollection!");
    }
}

public static void Main()
{
    FooCollection fooCollection = new FooCollection();
    fooCollection.Add(new Foo()); //OUTPUT: An item was successfully inserted to FooCollection!
}