Наслідуйте загальний базовий клас, застосуйте обмеження та реалізуйте інтерфейс у C #


117

Це синтаксичне запитання. У мене є загальний клас, який успадковується від загального базового класу і застосовує обмеження до одного з параметрів типу. Я також хочу, щоб похідний клас реалізував інтерфейс. За все життя я не можу зрозуміти правильний синтаксис.

Ось що я маю:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar { ... }

Перше, що прийшло в голову:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar, IFoo { ... }

Але це невірно, тому що T2 потребує реалізації як IBar, так і IFoo, а не DerivedFoo для реалізації IFoo.

Я трохи спробував гуглінг, використання кольорових точок, крапки з комою тощо, але я виявився коротким. Я впевнений, що відповідь головою ляпає просто.


Я не міг зрозуміти відповідь @ Адама, коли я подивився один раз, але через 2 хвилини я міг зрозуміти, що це таке, дякую за відповідь. Отриманий клас має більш ніж одну реалізацію, в цьому і полягає справа. У будь-якому випадку я хочу показати його позначення для інших. "клас DerivedClass <Type>: ParentClass, де Тип: IType". Нічого не повинно бути між останнім запровадженим класом і пунктом де
медсерезгін

Відповіді:


173

Ви включаєте весь підпис свого класу, перш ніж визначати загальні обмеження.

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}

5
Для інших я це інтерналізував як, клас отримує лише той пункт, де застереження, і він закінчується для будь-яких та всіх обмежень загального типу.
Енді V

@Visser Дозволено мати декілька де клаузи, клас Test <T1, T2> де T1: Interface1 де T2: Interface2
bwing

@ Віссер, так, що сказав bwing, також кожен, де застереження може мати кілька обмежень ... так що синтаксис з оригінальної публікації є правильним, він просто означає щось інше, що хотіла оп. where T2 : IBar, IFoo просто означає, що T2має реалізовувати обидва інтерфейси замість DerivedFoo<T1,T2> реалізаціїIFoo
v01pe

18

Моя рекомендація: коли у вас виникає запитання щодо синтаксису мови C #, прочитайте специфікацію; тому ми його публікуємо. Вам потрібно прочитати розділ 10.1.

Щоб відповісти на ваше конкретне запитання, порядок речей у декларації класу такий:

  • атрибути, у квадратних дужках
  • модифікатори ("загальнодоступні", "статичні" тощо)
  • "частковий"
  • "клас"
  • назва класу
  • список відокремлених комами оголошень параметрів типу всередині кутових дужок
  • двокрапка слідує розділеному комою списку базових типів (базовий клас та реалізовані інтерфейси; базовий клас повинен бути першим, якщо такий є)
  • обмеження параметрів типу
  • корпус класу, оточений брекетами
  • крапка з комою

Все в цьому списку є необов’язковим, крім "класу", назви та тіла, але все повинно бути в тому порядку, якщо воно з'являється.


95
Еріко, хоча я дуже поважаю тебе як професіонала і ціную твої відгуки, я не можу не розчаруватися тим, що трапляється як абразивна відповідь. Ви критикуєте мене за те, що я вирішив задати питання на програмувальному сайті Q&A щодо розміщення, завантаження та пошуку через високо технічну сторінку 503 Word Word, похований за посиланням у MSDN. Це досить грубо. Це було найефективнішим використанням мого часу та має додаткову перевагу, що згодом це може допомогти комусь іншому. Посилання на специфікацію C # Lang для зацікавлених: msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
Dan Rigby

17
Ніякої критики не передбачалося. Існує широка упередженість у чистотекстовій комунікації, яка робить прості висловлювання фактів звуковими і брутальними; Я намагаюся читати благодійно, коли мені подають список корисних фактів, і рекомендую зробити це також. Я стою за своєю рекомендацією; якщо у вас є питання щодо синтаксису, специфікація відповідає на них остаточно і починається з корисної таблиці змісту для визначення визначень конкретних синтаксисів.
Ерік Ліпперт

3
Ден, знайти C # spec так само просто, як ввести "C # Spec" в Google і натиснути кнопку "Мені пощастило". А якщо ви професійний розробник C #, у вас вже має бути на вашому комп'ютері специфікація C # у форматі PDF. Також я не хочу критикувати вас. Я раніше не звик читати специфікації, але я почав її читати завдяки Джону, Еріку та Павлу, які завжди цитують специфікацію C # за будь-яке питання. Я виявив, що специфікація C #, хоч часом її важко читати, - чудовий спосіб дізнатися про мову.
РішенняYogi

@Eric Lippert: Досить справедливо. Дякую за відповідь В якості конструктивної пропозиції було б корисно, якби Microsoft інтегрував вміст специфікації безпосередньо в MSDN, а також існував як окреме завантаження. Версія Visual Studio .Net MSDN має інтегровану версію специфікації, але не пізніші версії. Я думав придбати книгу Андерса Хейльберга, але з .Net 4.0 за кутом я поки що поки небажаний. amazon.com/C-Programming-Language-3rd/dp/0321562992 Дякую
Дан Рігбі

2
C ++ вимагає, щоб декларація класу закінчувалася крапкою з комою. Багато розробників C # походять із C ++; іноді їх пальці кладуть крапку з комою, не зачіпаючи їх. :-) У C # є декілька конструкцій, які беруть необов'язковий напівтермін, де C ++ вимагає його. Це майже просто тонка зручність. Я припускаю, що він також дозволяє вам тонко викликати, коли закінчується декларація типу, наприклад, декларація тіла методу.
Ерік Ліпперт

8
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }

2
public class KeyAndValue<T>
{
    public string Key { get; set; }
    public virtual T Value { get; set; }
}

public class KeyAndValue : KeyAndValue<string>
{
    public override string Value { get; set; }
}

Це розширення від існуючих відповідей. Він за замовчуванням застосовується, stringякщо ви не постачаєте тип. Я не реалізував інтерфейс, але це не повинно вимагати нічого іншого, ніж зазвичай.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.