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

Это синтаксический вопрос. У меня есть универсальный класс, который наследуется от универсального базового класса и накладывает ограничение на один из параметров типа. Я также хочу, чтобы производный класс реализовал интерфейс. Да хоть убей, я не могу понять правильный синтаксис.

Вот что у меня есть:

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

Первое, что пришло в голову:

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

Но это неверно, поскольку из-за этого T2 необходимо реализовать как IBar, так и IFoo, а не DerivedFoo для реализации IFoo.

Я пробовал немного погуглить, использовать двоеточия, точки с запятой и т. Д., Но у меня не получилось. Я уверен, что ответ невероятно прост.


person Dan Rigby    schedule 05.01.2010    source источник
comment
Я не мог понять ответа @Adam, когда посмотрел один раз, но через 2 минуты я смог понять, что это такое, спасибо за ответ. Производный класс имеет более одной реализации, может быть, в этом суть. В любом случае, я хочу показать другим его обозначения. class DerivedClass ‹Type›: ParentClass, где Тип: IType. Между последним реализованным классом и предложением where не должно быть ничего.   -  person nurisezgin    schedule 20.04.2019


Ответы (3)


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

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}
person Adam Robinson    schedule 05.01.2010
comment
Для других я усвоил это как класс получает только одно предложение where и идет в конце для любых и всех ограничений универсального типа. - person Andy V; 22.08.2016
comment
@Visser Допускается наличие нескольких предложений where, class Test ‹T1, T2›, где T1: Interface1, где T2: Interface2 - person bwing; 07.03.2018
comment
@Visser да, что сказал bwing, также каждое предложение where может иметь несколько ограничений ... так что синтаксис из исходного сообщения правильный, это просто означает что-то другое, что нужно op. where T2 : IBar, IFoo просто означает, что T2 должен реализовать оба интерфейса вместо DerivedFoo<T1,T2> реализации IFoo - person v01pe; 22.10.2018

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

Чтобы ответить на ваш конкретный вопрос, порядок вещей в объявлении класса:

  • атрибуты в квадратных скобках
  • модификаторы («общедоступный», «статический» и т. д.)
  • "частичный"
  • "класс"
  • название класса
  • разделенный запятыми список объявлений параметров типа внутри угловых скобок
  • двоеточие следует за разделенным запятыми списком базовых типов (базовый класс и реализованные интерфейсы, базовый класс должен идти первым, если он есть)
  • ограничения параметра типа
  • тело класса, окруженное фигурными скобками
  • точка с запятой

Все в этом списке необязательно, кроме «класса», имени и тела, но все должно появиться в этом порядке, если оно появляется.

person Eric Lippert    schedule 05.01.2010
comment
Эрик, хотя я очень уважаю вас как профессионала и ценю ваши отзывы, я не могу не разочароваться в том, что мне кажется резким ответом. Вы критикуете меня за то, что я решил задать вопрос на сайте вопросов и ответов по программированию вместо того, чтобы найти, загрузить и выполнить поиск по высокотехнологичному 503-страничному документу Word, скрытому по ссылке в MSDN. Это довольно грубо. Это было наиболее эффективное использование моего времени и дополнительное преимущество, заключающееся в том, что позже это может помочь кому-то другому. Ссылка на спецификацию языка C # для заинтересованных: msdn.microsoft.com/ en-us / vcsharp / aa336809.aspx - person Dan Rigby; 05.01.2010
comment
Никакой критики не предполагалось. В чистом текстовом общении существует повсеместная предвзятость, из-за которой простые изложения фактов кажутся резкими и резкими; Я стараюсь читать с милосердием, когда мне предоставляют список полезных фактов, и рекомендую вам поступить так же. Я поддерживаю свою рекомендацию; Если у вас есть вопросы о синтаксисе, спецификация дает на них исчерпывающие ответы и начинается с полезного оглавления, в котором можно найти определения конкретных синтаксисов. - person Eric Lippert; 05.01.2010
comment
Дэн, найти спецификацию C # так же просто, как ввести «C # Spec» в Google и нажать кнопку «Мне повезло». А если вы профессиональный разработчик C #, у вас уже должна быть спецификация C # в формате PDF на вашем компьютере. Кроме того, я тоже не хочу вас критиковать. Раньше я не привык читать спецификации, но я начал читать их благодаря Джону, Эрику и Павлу, которые всегда цитируют спецификацию C # по любому вопросу. Я обнаружил, что спецификация C #, хотя временами ее трудно читать, - отличный способ изучить язык. - person SolutionYogi; 05.01.2010
comment
@ Эрик Липперт: Достаточно справедливо. Спасибо за ваш ответ. В качестве конструктивного предложения было бы полезно, если бы Microsoft интегрировала содержимое спецификации непосредственно в MSDN в дополнение к тому, что она существовала в виде отдельной загрузки. Версия Visual Studio .Net MSDN имеет интегрированную версию спецификации, но не более поздние версии. Я подумал о покупке книги Андерса Хейлберга, но с приближением .Net 4.0 я пока не хочу. amazon.com/C-Programming-Language-3rd/dp/ 0321562992 Спасибо. - person Dan Rigby; 05.01.2010
comment
@SolutionYogi: Документ на веб-сайте MS находится в формате .doc (я знаю его местоположение, поскольку я ссылался на него в своем комментарии), где вы нашли версию PDF? Спасибо. - person Dan Rigby; 05.01.2010
comment
@SolutionYogi: Единственная загвоздка в том, что стандарт ECMA отстает от спецификации языка Microsoft C # в денежном выражении. Например, ECMA-334 не охватывает LINQ или Lambdas. Хотя это сработало бы для моего вопроса, я более склонен ссылаться на самый последний документ. - person Dan Rigby; 05.01.2010
comment
Вы абсолютно правы. Пока что для моих простых нужд работала версия в формате PDF. - person SolutionYogi; 05.01.2010
comment
Ух ты, ты что-то узнаешь каждый день ... не знал, что за определением класса может стоять точка с запятой (не знаю, зачем тебе это нужно, но я уверен, что на это есть причина). +1 - person Adam Robinson; 06.01.2010
comment
C ++ требует, чтобы объявление класса заканчивалось точкой с запятой. Многие разработчики C # пришли из C ++; иногда их пальцы ставят точку с запятой, а мозг не вмешивается. :-) В C # есть несколько конструкций, которые принимают необязательный полуавтомат, а для C ++ он нужен. Это просто тонкое удобство. Я полагаю, он также позволяет вам незаметно вызывать, когда объявление типа заканчивается, или, скажем, объявление тела метода. - person Eric Lippert; 06.01.2010

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, если вы не указываете тип. Я не реализовал интерфейс, но для этого не должно требоваться ничего, кроме обычного.

person user875234    schedule 31.08.2018