IEnumerable <T> как тип возврата

Неустранимая ошибка: Невозможно переопределить класс [имя класса]

Неустранимая ошибка: невозможно обновить [имя функции]

Это означает, что вы либо используете одно и то же имя функции / класса дважды, и вам нужно переименовать один из них, или это потому, что вы использовали require или include, где вы должны использовать require_once или include_once.

Когда класс или функция объявляется в PHP, он неизменен и не может быть позже объявлен с новым значением.

Рассмотрим следующий код:

class.php

<?php

class MyClass
{
    public function doSomething()
    {
        // do stuff here
    }
}

index.php

<?php

function do_stuff()
{
   require 'class.php';
   $obj = new MyClass;
   $obj->doSomething();
}

do_stuff();
do_stuff();

Второй вызов do_stuff() приведет к получению ошибка выше. Изменяя require на require_once, мы можем быть уверены, что файл, содержащий определение MyClass, будет загружен только один раз, и ошибка будет устранена.

28
задан DavidRR 3 December 2015 в 13:17
поделиться

7 ответов

Это - действительно два вопроса о части.

1) там по сути что-то не так с возвратом IEnumerable< T>

No ничто вообще. На самом деле при использовании итераторов C#, это - ожидаемое поведение. Преобразование его к List< T> или другой класс набора преимущественно не является хорошей идеей. Выполнение так делает предположение на шаблоне использования Вашей вызывающей стороной. Я нахожу, что это не хорошая идея принять что-либо о вызывающей стороне. У них могут быть серьезные основания, почему они хотят IEnumerable< T>. возможно, они хотят преобразовать его в совершенно другую иерархию набора (в этом случае, преобразование в Список потрачено впустую).

2) там любые обстоятельства, где может быть предпочтительно возвратить что-то другое, чем IEnumerable< T>?

Да. В то время как это не прекрасная идея принять много о Ваших вызывающих сторонах, это должно отлично хорошо принять решения на основе Вашего собственного поведения. Вообразите сценарий, где у Вас был многопоточный объект, который был организацией очередей, запрашивает в объект, который постоянно обновлялся. В этом случае, возвращая необработанный IEnumerable< T> является безответственным. Как только набор изменяется, счетное делается недействительным и заставит execption происходить. Вместо этого Вы могли взять снимок структуры и возврата то значение. Скажите в List< T> форма. В этом случае я просто возвратил бы объект как прямую структуру (или интерфейс).

Это - конечно, более редкий случай все же.

29
ответ дан JaredPar 28 November 2019 в 02:42
поделиться

Нет, IEnumerable<T> хороши вещь возвратиться сюда, начиная со всего, что Вы обещаете, "последовательность (введенных) значений". Идеал для LINQ и т.д., и совершенно применимый.

вызывающая сторона может легко поместить эти данные в список (или безотносительно) - особенно с LINQ (ToList, ToArray, и т.д.).

Этот подход позволяет Вам лениво буферизовать назад значения, вместо того, чтобы иметь необходимость буферизовать все данные. Определенно положительный герой. Я записание другое полезное IEnumerable<T> прием на днях, также.

27
ответ дан Marc Gravell 28 November 2019 в 02:42
поделиться

О Вашем принципе: "примите наименьшее, Вы можете, но возвращать максимум".

ключ к управлению сложностью большой программы является техникой, названной сокрытие информации . Если Ваш метод работает путем создания List<T>, не часто необходимо показать этот факт путем возврата того типа. Если Вы делаете, то Ваши вызывающие стороны могут изменить список, который они возвращают. Это удаляет Вашу способность сделать кэширование или ленивое повторение с yield return.

, Таким образом, лучший принцип для функции для следования: "покажите как можно меньше о том, как Вы работаете".

4
ответ дан Daniel Earwicker 28 November 2019 в 02:42
поделиться

IEnumerable меня устраивает, но он имеет некоторые недостатки. Клиент должен перечислить для получения результатов. Это не имеет никакого способа проверить на количество и т.д. Список плох, потому что Вы представляете слишком много управления; клиент может добавить/удалить и т.д. от него, и это может быть плохой вещью. Набор кажется лучшим compromomise, по крайней мере, в представлении FxCop. Я всегда использую то, что кажется appropiate в моем контексте (например, если я хочу возвратить набор только для чтения, я представляю набор как тип возврата и Список возврата. AsReadOnly () или IEnumerable для отложенных вычислений через урожай и т.д.). Возьмите его на индивидуальной основе

4
ответ дан Backwards_Dave 28 November 2019 в 02:42
поделиться

Возврат IEnumerable< T> в порядке, если Вы по-настоящему только возвращаете перечисление, и оно будет использовано Вашей вызывающей стороной как таковой.

, Но поскольку другие указывают, это имеет недостаток, который вызывающая сторона, возможно, должна перечислить, если ему нужна какая-либо другая информация (например, количество)..NET 3,5 дополнительных метода IEnumerable< T>.Count перечислит негласно, если возвращаемое значение не реализует ICollection< T> который может быть нежелательным.

я часто возвращаю IList< T> или ICollection< T> когда результатом является набор - внутренне, Ваш метод может использовать List< T> и или возвратите его как есть или возвратите List< T>.AsReadOnly, если Вы хотите защитить от модификации (например, если Вы кэшируете список внутренне). AFAIK FxCop довольно доволен любым из них.

2
ответ дан Joe 28 November 2019 в 02:42
поделиться

Просто, потому что Вы говорите, что возвращаетесь, IEnumerable не означает, что Вы не можете возвратить Список. Идея состоит в том, чтобы уменьшить ненужную связь. Все, о чем должна заботиться вызывающая сторона, получает список вещей, а не точный тип набора раньше содержал тот список. Если у Вас есть что-то, что это поддерживается массивом, то получение чего-то как количество будет быстрым так или иначе.

1
ответ дан Yuliy 28 November 2019 в 02:42
поделиться

Я думаю, что Ваше собственное руководство является большим - если Вы в состоянии быть более конкретными относительно того, что Вы возвращаете без хита производительности (Вы не имеете к, например, создаете Список из своего результата), сделайте так. Но если Ваша функция законно не знает то, что вводит, она собирается найти, как то, если в некоторых ситуациях Вы будете работать со Списком и в некоторых с Массивом, и т.д., затем возвращение IEnumerable является "лучшим", чтобы можно было сделать. Думайте о нем как о "самом большом общем множителе" всего, что Вы могли бы хотеть возвратить.

0
ответ дан Coderer 28 November 2019 в 02:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: