Одне поширене використання цього пов'язане з поняттям власних типів: параметр типу, який відповідає поточному типу. Скажімо, ви хочете визначити інтерфейс із clone()
методом. clone()
Метод завжди повинен повертати екземпляр класу , на якому він був викликаний. Як ви заявляєте про цей метод? У системі генерики, яка має власні типи, це легко. Ви просто говорите, що це повертається self
. Отже, якщо у мене є клас Foo
, метод повернення повинен бути оголошений для повернення Foo
. У Java та (з побіжного пошуку) C # це не варіант. Натомість ви бачите декларації, як те, що ви бачите в цьому класі. Важливо розуміти, що це не те саме, що для самовведення, і обмеження, які він надає, слабші. Якщо у вас є клас Foo
і Bar
клас, з якого походять обидваBasePage
, ви можете (якщо я не помиляюся) визначити Foo для параметра Bar
. Це може бути корисним, але я думаю, як правило, більшу частину часу це буде використовуватися як власний тип, і це просто зрозуміло, що хоч ти можеш обходити і замінювати інші типи, це не те, що ти повинен робити. Я давно розігрувався з цією ідеєю, але дійшов висновку, що докладати зусиль не варто, оскільки обмеження Java-дженерики. Звичайно, загальна інформація про C # є більш повною, але, мабуть, має таке саме обмеження.
Інший раз, коли цей підхід застосовується, це коли ви будуєте такі типи графіків, як дерева або інші рекурсивні структури. Декларація дозволяє типам відповідати вимогам сторінки, але додатково уточнювати тип. Ви можете бачити це в структурі дерева. Наприклад, Node
може бути параметризований параметр, Node
який дозволить реалізаціям визначити, що це не просто Дерева, що містять будь-який тип Вузла, а певний підтип Вузла (як правило, їх власний тип.) Я думаю, що це більше того, що тут відбувається.