Если Вы, как предполагается, не возвращаете наборы вызывающим сторонам, как необходимо возвратить набор данных вызывающей стороне?

5
задан Kyle Trauberman 10 December 2009 в 16:37
поделиться

9 ответов

Основная причина этого ограничения заключается в том, что оно нарушает полиморфизм, константность и контроль доступа, если класс возвращает член коллекции. Если вы создаете коллекцию для возврата, а класс не сохраняет ее в качестве члена, то это не проблема.

Тем не менее, вы, возможно, захотите больше подумать о том, почему вы хотите вернуть эту коллекцию. Что вы хотите, чтобы вызывающий класс мог делать с данными? Можете ли вы реализовать эту функциональность, добавив методы в свой класс вместо возврата коллекции (например, myobj.getvalueFromKey (s) вместо myobj.getdictionary () [s])? Может быть, было бы более подходящим вернуть объект, который предоставляет только ту информацию, которую вы хотите, а не просто вернуть коллекцию (например, MyLookupTable MyClass :: getLookupTable (), а не IDictionary MyClass ::

7
ответ дан 18 December 2019 в 09:07
поделиться

Общее мнение о возвращении типы коллекции из вызовов методов не делать.

Я впервые слышу это, и это кажется мне глупым ограничением.

Я понимаю причины этого policy

Какие они тогда?

Редактировать: Причины, по которым вы указываете против возврата коллекций, являются конкретными потенциальными проблемами, которые могут быть решены конкретно (путем возврата оболочки только для чтения) без общих ограничений на возврат коллекций. Но насколько я понимаю вашу ситуацию, коллекция на самом деле создается этим методом - в этом случае изменения, внесенные вызывающей стороной, не повлияют ни на что другое, и, следовательно, вам не о чем действительно нужно беспокоиться, и вы не должны чрезмерно ограничивать что вызывающий должен делать с объектом, созданным специально для него.

10
ответ дан 18 December 2019 в 09:07
поделиться

Я никогда не слышал этого совета. Если вы сделаете это неправильно, могут возникнуть проблемы с безопасностью потоков, но вы можете обойти это, если нужно.

0
ответ дан 18 December 2019 в 09:07
поделиться

На мой взгляд, возвращение коллекций является проблемой только в том случае, если изменение возвращаемой коллекции может иметь побочные эффекты, например. несколько функций работают с одной и той же коллекцией.

Если вы только создаете коллекцию, а не делаете данные из класса общедоступными посредством возврата коллекции, я думаю, можно просто вернуть словарь

Если коллекция используется где-то в другом месте вашего кода и код, который вы вернули, collection не должна иметь возможность изменять коллекцию, которую вы должны клонировать.

Если вы только создаете коллекцию, а не делаете данные из класса общедоступными посредством возврата коллекции, я думаю, можно просто вернуть словарь

Если коллекция используется где-то в другом месте вашего кода и код, который вы вернули, collection не должна иметь возможность изменять коллекцию, которую вы должны клонировать.

Если вы только создаете коллекцию, а не делаете данные из класса общедоступными посредством возврата коллекции, я думаю, можно просто вернуть словарь

Если коллекция используется где-то в другом месте вашего кода и код, который вы вернули, collection не должна иметь возможность изменять коллекцию, которую вы должны клонировать.

1
ответ дан 18 December 2019 в 09:07
поделиться

Для этого обратитесь к ReadOnlyCollection (). Измените тип возвращаемого значения и последний оператор на

return new ReadOnlyCollection(whateverYouWereReturningBefore);
0
ответ дан 18 December 2019 в 09:07
поделиться

Возможно, проблема связана с коллекциями только для чтения (т.е. неизменяемыми коллекциями)? Если так, то есть отличная серия сообщений Эрика Липперта , в которой подробно рассказывается, как их построить.

Цитата: Гораздо легче рассуждать о структуре данных, если вы знайте, что это никогда не изменится. Поскольку они не могут быть изменены, они автоматически являются потокобезопасными. Поскольку они не могут быть изменены, вы можете поддерживать стек прошлых «снимков» структуры, и внезапно реализации отмены-повтора становятся тривиальными.

0
ответ дан 18 December 2019 в 09:07
поделиться

Я обычно возвращаю массив данных по типу коллекции. В C #, например, многие коллекции реализуют метод .toArray (), а для тех, которые этого не делают, массив может быть получен с помощью лямбда-выражений.

Edit

Видел ваш комментарий к «No Refunds No Возвращает "ответ. Если вы возвращаете словарь, массив может вам не подойти. В этом случае я бы рекомендовал вернуть интерфейс, а не конкретную реализацию.

В C # (например):

public IDictionary<string, object> MyMethod()
{
    Dictionary<string, object> myDictionary = new Dictionary<string, object>();

    // do stuff here

    return myDictionary;
}

Редактировать 2

Возможно, вам потребуется реализовать свой собственный класс словаря, доступный только для чтения, и выбросить исключение в необходимых методах для предотвращения добавления и т. д.

В C # (Опять же, например) (Не полное решение):

public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    private IDictionary<TKey, TValue> _innerDictionary;

    public ReadOnlyDictionary(IDictionary<TKey, TValue> innerDictionary)
    {
        this._innerDictionary = innerDictionary;
    }

    public void Add(TKey key, TValue value)
    {
        throw new NotImplementedException();
    }

    public bool Remove(TKey key)
    {
        throw new NotImplementedException();
    }

    public void Add(KeyValuePair<TKey, TValue> item)
    {
        throw new NotImplementedException();
    }

    public void Clear()
    {
        throw new NotImplementedException();
    }

    public bool IsReadOnly
    {
        get { return true; }
    }

    public bool Remove(KeyValuePair<TKey, TValue> item)
    {
        throw new NotImplementedException();
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return _innerDictionary.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _innerDictionary.GetEnumerator();
    }
}
0
ответ дан 18 December 2019 в 09:07
поделиться

Как насчет возврата IEnumerable , вызывающего затем можно легко отфильтровать результаты в любом случае через linq без изменения исходной структуры.

очевидно, для словаря это будет IEnumerable >

Изменить: для поиска вы, вероятно, хотите ToLookup () расширение и ILookup

0
ответ дан 18 December 2019 в 09:07
поделиться

Я слышал, что я не разрешил такое поведение, потому что тип коллекции или словаря, предназначенный для использования (но не изменения) клиентом, демонстрирует слишком много поведения, создавая иллюзию, что вызывающий объект может изменить тип.

Но это не иллюзия. Вызывающий может изменять тип (ну, экземпляр типа). Почему, черт возьми, это проблема?

По той же логике DataTable.Select () не должен возвращать DataRow [] , поскольку вызывающий может не только управлять членством в этом массиве, он может изменять базовые данные!

И идея возврата неизменяемого словарного класса, который имеет метод ToDictionary () : что возможно выгода от этого?

Верно, что возвращение неизменяемых объектов дает вам возможность реализовать интернирование без изменения вашего API. Но это единственное преимущество, о котором я могу думать.

0
ответ дан 18 December 2019 в 09:07
поделиться
Другие вопросы по тегам:

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