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

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

Дэн Ригби
источник
Я не мог понять ответ @Adam, когда посмотрел один раз, но через 2 минуты я смог понять, что это такое, спасибо за ответ. Производный класс имеет более одной реализации, может быть, в этом суть. В любом случае я хочу показать его обозначения другим. "класс DerivedClass <Type>: ParentClass, где Type: IType". Между последним реализованным классом и предложением where не должно быть ничего.
нурисезгин

Ответы:

173

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

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}
Адам Робинсон
источник
5
Для других я усвоил это как класс получает только одно предложение where, и он идет в конце для любых и всех ограничений универсального типа.
Andy V,
@Visser Разрешено иметь несколько предложений where, class Test <T1, T2>, где T1: Interface1, где T2: Interface2
bwing 06
@Visser да, что сказал bwing, также каждое предложение where может иметь несколько ограничений ... так что синтаксис из исходного сообщения правильный, это просто означает что-то другое, что нужно оператору. where T2 : IBar, IFoo просто означает, что T2необходимо реализовать оба интерфейса вместо DerivedFoo<T1,T2> реализацииIFoo
v01pe
18

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

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

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

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

Эрик Липперт
источник
95
Эрик, хотя я очень уважаю вас как профессионала и ценю ваши отзывы, я не могу не расстроиться, увидев резкий ответ. Вы критикуете меня за то, что я решил задать вопрос на сайте вопросов и ответов по программированию вместо того, чтобы найти, загрузить и выполнить поиск по высокотехнологичному 503-страничному документу Word, скрытому по ссылке в MSDN. Это довольно грубо. Это было наиболее эффективное использование моего времени и дополнительное преимущество, заключающееся в том, что позже это может помочь кому-то другому. Ссылка на спецификацию языка C # для заинтересованных: msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
Дэн Ригби
17
Никакой критики не предполагалось. В чистом текстовом общении существует повсеместная предвзятость, из-за которой простые изложения фактов кажутся резкими и резкими; Я стараюсь читать с милосердием, когда мне предоставляют список полезных фактов, и рекомендую вам поступить так же. Я придерживаюсь своей рекомендации; Если у вас есть вопросы о синтаксисе, спецификация дает на них окончательные ответы и начинается с полезного оглавления, в котором можно найти определения конкретных синтаксисов.
Эрик Липперт
3
Дэн, найти спецификацию C # так же просто, как ввести «C # Spec» в Google и нажать кнопку «Мне повезло». А если вы профессиональный разработчик C #, у вас уже должна быть спецификация C # в формате PDF на вашем компьютере. Кроме того, я тоже не хочу вас критиковать. Раньше я не привык читать спецификации, но я начал читать их благодаря Джону, Эрику и Павлу, которые всегда цитируют спецификацию C # по любому вопросу. Я обнаружил, что спецификация C #, даже несмотря на то, что иногда ее трудно читать, является отличным способом изучить язык.
SolutionYogi
@ Эрик Липперт: Достаточно справедливо. Спасибо за ваш ответ. В качестве конструктивного предложения было бы полезно, если бы 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если вы не указываете тип. Я не реализовал интерфейс, но для этого не должно требоваться ничего, кроме обычного.

user875234
источник