Унаследовать от базового базового класса, применить ограничение и реализовать интерфейс в C # - PullRequest
93 голосов
/ 05 января 2010

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

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

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

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

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

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

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

Ответы [ 4 ]

139 голосов
/ 05 января 2010

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

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}
16 голосов
/ 05 января 2010

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

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

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

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

7 голосов
/ 05 января 2010
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }
2 голосов
/ 31 августа 2018
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, если вы не указали тип. Я не реализовал интерфейс, но для этого не нужно ничего другого, чем обычно.

...