3

我从一位客户那里得到了一些代码,如下所示:

public class Thing
{
    // custom functionality for Thing...
}

public class Things : IEnumerable
{
    Thing[] things;
    internal int Count { get { return things.Length; } }

    public Thing this[int i] { get { return this.things[i]; } }

    public IEnumerator GetEnumerator() { return new ThingEnumerator(this); }

    // custom functionality for Things...
}

public class ThingEnumerator : IEnumerator
{
    int i;
    readonly int count;
    Things container;

    public ThingEnumerator(Things container)
    {
        i = -1;
        count = container.Count;
        this.container = container;
    }

    public object Current { get { return this.container[i]; } }
    public bool MoveNext() { return ++i < count; }
    public void Reset() { i = -1; }
}

我想知道的是,摆脱ThingEnumerator类并将Things.GetEnumerator调用替换为简单地委托给array's的实现是否会更好GetEnumerator?像这样:

public IEnumerator GetEnumerator() { return things.GetEnumerator(); }

保持代码不变有什么好处吗?(我注意到的另一件事是现有代码可以通过替换来改进IEnumeratorIEnumerator<Thing>

4

5 回答 5

3

IEnumerable使用泛型,实现和你自己的价值真的很小IEnumerator

删除这些是用通用集合替换类意味着您需要维护的代码要少得多,并且具有使用已知可以工作的代码的优势。

于 2013-05-13T10:25:46.363 回答
2

在一般情况下,有时可能有理由实现您自己的枚举器。您可能需要一些内置功能不提供的功能 - 一些验证、日志记录、在某处引发 OnAccess 类型的事件,可能需要一些逻辑来锁定项目并在之后释放它们以进行并发访问(我见过这样做的代码最后一个;这很奇怪,我不推荐它)。

话虽如此,我在您发布的示例中看不到任何类似的东西,所以它似乎没有增加任何超出IEnumerable提供的价值。通常,如果有内置代码可以满足您的需求,请使用它。通过自己滚动,您将实现的只是创建更多代码来维护。

于 2013-05-13T10:32:04.630 回答
2

您拥有的代码看起来像在 .NET 泛型可用之前为 .NET 1.0/1.1 编写的代码 - 那时,实现您自己的集合类(通常派生自System.Collections.CollectionBase)是有价值的,以便可以键入索引器属性到集合的运行时类型。但是,除非您使用值类型并且装箱/拆箱是性能限制,否则我将继承自CollectionBase,并且无需重新定义GetEnumerator()or Count

但是,现在,我会推荐以下两种方法之一:

  1. 如果您需要自定义集合具有一些自定义功能,则从集合派生System.Collections.ObjectModel.Collection<Thing>- 它为您提供所有必要的挂钩来控制集合中项目的插入、替换和删除。

  2. 如果您实际上只需要需要枚举的东西,我会返回一个IList<Thing>List<Thing>.

于 2013-05-13T10:33:30.480 回答
1

除非您在自定义枚举器中执行真正自定义的操作(例如某种验证),否则确实没有任何理由这样做。

通常,除非有明确的理由不这样做,否则请使用标准库中可用的内容。作为单独的代码单元,它们可能经过了更好的测试并且花费了更多的时间,那么您可以负担得起,为什么要重新创建轮子?

在这种情况下,代码已经存在,但如果您有时间进行很好的测试,替换代码可能会更好。(如果有不错的单元测试覆盖率,这很容易。)

您将减少维护开销,消除潜在的隐蔽错误来源,并使代码比您发现的更干净。鲍勃叔叔会很自豪的。

于 2013-05-13T10:27:32.427 回答
1

数组枚举器与您的自定义枚举器几乎相同,所以是的,您也可以直接返回数组的枚举器。
在这种情况下,我建议您这样做,因为数组枚举器还执行更多错误检查,并且正如您所说,它更简单。

于 2013-05-13T10:31:05.970 回答