Я натрапив на цю ситуацію. Фактично, як вказувалося інших місцях, у БКЛ є такі випадки ... Я спробую навести кращі приклади та навести деякі обґрунтування:
Коли у вас вже є інтерфейс, що постачається, який ви зберігаєте з міркувань сумісності та ...
Інтерфейс містить членів, які застаріли або видалені. Наприклад, BlockingCollection<T>.ICollection.SyncRoot
(серед інших), якщо ICollection.SyncRoot
вона сама по собі не застаріла, вона кинеться NotSupportedException
.
Інтерфейс містить учасників, задокументованих як необов'язкові, і реалізація може кинути виняток. Наприклад, про MSDN щодо IEnumerator.Reset
цього написано:
Метод Скидання передбачений для сумісності з COM. Це не обов'язково потрібно реалізовувати; натомість реалізатор може просто кинути NotSupportedException.
Помилково оформляючи інтерфейс, у першу чергу це повинно було бути більше одного інтерфейсу. Це звичайна модель в BCL для реалізації версій контейнерів з читанням NotSupportedException
. Я це зробив сам, це те, що зараз очікується ... Я ICollection<T>.IsReadOnly
повертаюсяtrue
щоб ви могли сказати їм про себе. Правильна конструкція мала б мати читану версію інтерфейсу, і тоді повний інтерфейс успадковується від цього.
Немає кращого інтерфейсу для використання. Наприклад, у мене є клас, який дозволяє вам отримувати доступ до елементів за індексом, перевіряйте, чи містить він елемент, а за яким індексом він має якийсь розмір, ви можете скопіювати його в масив ... це здається роботою, IList<T>
але мій клас має фіксованого розміру і не підтримує додавання та видалення, тому він працює більше як масив, ніж список. Але є НЕ IArray<T>
в BCL .
Інтерфейс належить API, який переноситься на кілька платформ, а при реалізації певної платформи деякі його частини не підтримуються. В ідеалі був би якийсь спосіб його виявити, так що портативний код, який використовує такий API, може вирішувати, чи не називати ці частини ... чи, якщо ви їх зателефонуєте, це цілком доречно NotSupportedException
. Це особливо вірно, якщо це порт на нову платформу, яка не була передбачена в оригінальному дизайні.
Також врахуйте, чому це не підтримується?
Іноді InvalidOperationException
кращий варіант. Наприклад, ще одним способом додати поліморфізм до класу є різноманітна реалізація внутрішнього інтерфейсу, і ваш код вибирає, який саме інстанціювати, залежно від параметрів, наведених у конструкторі класу. [Це особливо корисно, якщо ви знаєте, що набір опцій виправлений, і ви не хочете дозволити вводити сторонні класи шляхом введення залежностей.] Я зробив це, щоб підтримати ThreadLocal оскільки реалізація відстеження та відстеження є Занадто далеко, і що може впливати на непростежувальну реалізацію? навіть тхо , це не залежить від стан об’єкта. У цьому випадку я сам представив клас, і я знав, що цей метод потрібно реалізувати, просто кинувши виняток.ThreadLocal.Values
InvalidOperationException
Іноді значення за замовчуванням має сенс. Наприклад, у ICollection<T>.IsReadOnly
згаданому вище, має сенс просто повернути «треть» або «фальсифікат» залежно від випадку. Отже ... що таке семантика IFoo.Bar
? можливо, якесь розумне значення за замовчуванням повернути.
Додаток: якщо ви керуєте інтерфейсом (і вам не потрібно залишатися з ним для сумісності), не повинно бути випадків, коли вам доведеться кидати NotSupportedException
. Хоча, можливо, вам доведеться розділити інтерфейс на два або більше менших інтерфейсу, щоб вони правильно підходили до вашого випадку, що може призвести до «забруднення» в екстремальних ситуаціях.