Хочу сделать IGenericInterface, где T: ISomethingElse //т.е. тип реализующего класса

#c# #generics #where-clause #where

#c# #дженерики #предложение where

Вопрос:

Я хочу использовать this ключевое слово или что-то подобное typeof(this) в where ограничении моего универсального интерфейса, но, по-видимому, это неверно (ни то, ни другое не компилируется). Есть ли простой способ сделать это, о котором я не знаю?

 interface IParent<TChild> where TChild : IChildOf<typeof(this)>
{

    void AddRange(TChild children){}

}

interface IChildOf<TParent> : IDisposable
{
    TParent Parent { get; }
}
  

Или я должен сделать

 interface IParent<TChild, T2> where TChild : IChildOf<T2>
  

и просто знайте, что T2 будет классом, реализующим интерфейс?

Комментарии:

1. this не имеет смысла в контексте, в котором вы пытаетесь использовать.

2. Привет, чего ты пытаешься достичь? Древовидная структура, в которой каждый узел имеет несколько дочерних элементов?

Ответ №1:

Здесь может быть использован любопытно повторяющийся общий шаблон:

 interface IParent<TChild, TParent>
  where TChild : IChildOf<TParent>
  where TParent : IParent<TChild, TParent>
{
  void AddRange(TChild children);
}
  

Но я бы серьезно подумал о переоценке вашего дизайна. Вам действительно нужно это?

Комментарии:

1. 1 и отметил ответ, в итоге я просто полностью удалил TParnet и сделал только IParent<TChild> . Спасибо.

2. @dFlat: Рад слышать о вашем изменении дизайна. Я занимался C # годами, активно используя дженерики, но использовал CRGP только один раз. 🙂

Ответ №2:

Я думаю, что ваш единственный выбор:

 interface IParent<TChild, TParent> where TChild : IChildOf<TParent>
{
    void AddRange(TChild children);
}
  

Вы можете использовать только параметры типа или известные типы во время компиляции в ограничениях типа для вашего универсального интерфейса, так что это лучшее, что вы можете сделать.

Ответ №3:

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

 interface INode
{
    List<INode> Children { get; }
    void AddRange(IEnumerable<INode> children);
}

class Node : INode
{
    List<INode> Children { get; private set; }

    void AddRange(IEnumerable<INode> children)
    {
        Children.AddRange(children);
    }
}