#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);
}
}