Есть ли когда-нибудь оправдание для исключения из неявного преобразования? - PullRequest
6 голосов
/ 08 октября 2009

С MSDN :

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

Хотя я не согласен с какой-либо конкретной точкой и согласен с тем, что все это очень хорошо, есть ли когда-нибудь причина, которая достаточно велика, чтобы оправдать нарушение части о неявных преобразованиях, не вызывающих исключения?

Частный случай, который я имею перед собой, - это тот случай, когда:

  1. У меня есть функция, которая возвращает пользовательский объект коллекции (мы назовем его FooCollection).
  2. Эта функция может возвращать коллекции с одним элементом, и по исходному коду можно определить, произойдет ли это . (под этим я подразумеваю только вызов функции, а не саму функцию)
  3. Если это произойдет, то вероятность того, что пользователь захочет этот отдельный элемент, составляет 99,9%, а не коллекции с одним элементом.

Теперь я спрашиваю, стоит ли включать неявное преобразование из FooCollection => Foo, чтобы скрыть эту маленькую деталь реализации, но это преобразование будет работать, только если в коллекции есть один элемент.

Можно ли в этом случае бросить Exception? Или я должен использовать явное приведение вместо? Любые другие идеи о том, как я мог бы справиться с этим (нет, из-за деталей реализации я не могу просто использовать две функции)?

РЕДАКТИРОВАТЬ: Я считаю, что стоит отметить, что FooCollection не реализует никаких интерфейсов или фактически расширяет Collection, как может означать название, поэтому ответы на основе LINQ бесполезны. Кроме того, хотя в коллекции реализован числовой индекс, это не самый интуитивно понятный способ работы с коллекцией, поскольку в основном он использует именованный индекс.

Ответы [ 4 ]

10 голосов
/ 08 октября 2009

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

Я бы точно не стал предоставлять неявное преобразование в этом случае. Даже идея явного приведения мне кажется неправильной: Foo x = (Foo)fooCollection просто кажется неправильным.

Почему бы вам просто не позволить вызывающему коду беспокоиться о преобразовании из FooCollection в Foo? Код будет гораздо более понятным для всех:

Foo a = fooCollection[0];
Foo b = fooCollection.First();
Foo c = fooCollection.FirstOrDefault();
// etc
1 голос
/ 08 октября 2009

Это явно не в порядке. Никогда не используйте исключения для реализации логики!

Вы можете использовать Linq-Statement FooCollection.FirstOrDefault(), который даст ноль или первый элемент.

0 голосов
/ 08 октября 2009

Неявное копроверсия, которая работает, только если в коллекции только 1 элемент? Итак, на самом деле, это не работает большую часть времени?

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

0 голосов
/ 08 октября 2009

Приведение должно быть явным. Будет очень странно иметь возможность назначить FooCollection для Foo без хотя бы приведения.

При этом ИМХО приведение не является хорошим способом сделать это. Даже если вы скажете «нет», я воспользуюсь функцией, потому что даже если у вас нет контроля над реализацией этих классов, вы можете по крайней мере добавить методы расширения, например Foo ToFoo(this FooCollection collection), чтобы выполнить работу.

...