множественный любопытно повторяющийся шаблон шаблона (CRTP) в С#?

Я пытаюсь внедрить интерфейс CRTP в свой код, но ограничение заставляет меня застрять. как реализовать ограничения, если у меня структура кода выглядит так? Это законно? Спасибо.

interface IInterface<T>
    where T: IInterface<T>
{
    //bla bla bla
    T Member { get; set; }
}
interface ITest1<iTest2, iTest1> : IInterface<iTest2>
{
    //bla bla bla
}
interface ITest2<iTest1, iTest3> : IInterface<iTest1>
{
    iTest3 RefMember { get; set; }
    //bla bla bla
}
interface ITest3<iTest2>
{
    List<iTest2> manyTest { get; set; }
    //bla bla bla
}
class Test1 : ITest1<Test2, Test1>
{
    //bla bla bla
}
class Test2 : ITest2<Test1, Test3>
{
    //bla bla bla
}
class Test3 : ITest3<Test2>
{
    //bla bla bla    
}

person user2277061    schedule 20.04.2013    source источник
comment
Вы пытались скомпилировать свой код? Если он не компилируется, какую ошибку вы получаете?   -  person svick    schedule 21.04.2013
comment
этот код неверен :), даже если компилятор это позволяет (interface IInterface<T> where T : IInterface<T> и др.). Я думаю, вы лучше всего объясните, что вы хотите, структура, которую вы имеете.   -  person NSGaga-mostly-inactive    schedule 21.04.2013
comment
@svick, если код написан так, у меня нет ошибок. Но когда я пытаюсь добавить ограничения, у меня начинает болеть голова .ITest1<iTest2, iTest1> : Entity<iTest1> where iTest2 : ITest2<ITest1<iTest2,iTest1>,ITest3<ITest1<iTest2,iTest1>,..... (?????)   -  person user2277061    schedule 21.04.2013
comment
@NSGaga Я читал блог Эрика Липперта, он сказал: › class Blah<T> where T : Blah<T> › Это кажется круговым (по крайней мере) в двух направлениях. Это действительно законно? › Да, это законно, и у него есть законное применение... В моем случае у меня 2 игрока, у каждого по 10 пешек. И каждая пешка будет размещена на доске размером 5 x 5. Каждая точка моей доски имеет разные ссылки на ходы. отображение такое. Каждая пешка будет копировать ссылки на ход со своей точки. thumbnails101.imagebam.com/25012/afd0fd250112805.jpg?nc   -  person user2277061    schedule 21.04.2013
comment
@user2277061 user2277061 Я думаю, это не похоже на то, что вы должны моделировать с использованием системы типов.   -  person svick    schedule 21.04.2013
comment
Я согласен - в крайних случаях это может быть "законно" (и компилируется) - но у вас, кажется, древовидная структура - и вам может понадобиться определенная структура. Но я не вижу там много types, кроме Pawn, Point и даже не того, что должно быть общим.   -  person NSGaga-mostly-inactive    schedule 21.04.2013
comment
@svick Да, это все моя ошибка, я думаю, что могу таким образом подключить какой-то объект с тем же интерфейсом. Но я получил много ошибок. Я думаю, что я могу создать интерфейс, в котором у них будет один и тот же интерфейс.   -  person user2277061    schedule 22.04.2013
comment
@NSGaga Думаю, я должен изменить свою структуру.   -  person user2277061    schedule 22.04.2013


Ответы (1)


 public abstract class MyBase
{
    /// <summary>
    /// The my test method. divyang
    /// </summary>
    public virtual void MyVirtualMethodWhichIsOverridedInChild()
    {
        Console.Write("Method1 Call from MyBase");
    }

    /// <summary>
    /// The my another test method.
    /// </summary>
    public abstract void MyAnotherTestMethod();

    /// <summary>
    /// The my best method.
    /// </summary>
    public virtual void MyVirualMethodButNotOverridedInChild()
    {
        Console.Write("Method2 Call from MyBase");
    }
}

теперь сделайте базовый класс

public abstract class CrtpBaseWrapper<T> : MyBase
    where T : CrtpBaseWrapper<T>
{
}

тогда вы можете сделать свой подкласс

public class CrtpChild : CrtpBaseWrapper<CrtpChild>
{
    /// <summary>
    /// The my test method. divyang
    /// </summary>
    public override void MyVirtualMethodWhichIsOverridedInChild()
    {
        Console.Write("Method1 Call from CrtpChild");
    }

    /// <summary>
    /// The my another test method.
    /// </summary>
    public override void MyAnotherTestMethod()
    {
        Console.Write("MyAnotherTestMethod Call from CrtpChild");
    }
}
person divyang4481    schedule 22.01.2014
comment
наконец-то я воспользовался вашим методом. Спасибо - person user2277061; 04.02.2014