Я натрапив на цю ситуацію. Фактично, як вказувалося інших місцях, у БКЛ є такі випадки ... Я спробую навести кращі приклади та навести деякі обґрунтування:
Коли у вас вже є інтерфейс, що постачається, який ви зберігаєте з міркувань сумісності та ...
Інтерфейс містить членів, які застаріли або видалені. Наприклад, 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.ValuesInvalidOperationException
Іноді значення за замовчуванням має сенс. Наприклад, у ICollection<T>.IsReadOnlyзгаданому вище, має сенс просто повернути «треть» або «фальсифікат» залежно від випадку. Отже ... що таке семантика IFoo.Bar? можливо, якесь розумне значення за замовчуванням повернути.
Додаток: якщо ви керуєте інтерфейсом (і вам не потрібно залишатися з ним для сумісності), не повинно бути випадків, коли вам доведеться кидати NotSupportedException. Хоча, можливо, вам доведеться розділити інтерфейс на два або більше менших інтерфейсу, щоб вони правильно підходили до вашого випадку, що може призвести до «забруднення» в екстремальних ситуаціях.