mardi 24 octobre 2017

Generic interface inheritance castings

Currently, I'm facing up with a generic interfaces inheritance problem:

interface IParent<T> {
    R Accept<R>(IParentVisitor<T, R> visitor);
}

interface IChild<T, TKey> : IParent<T> {
   R Accept<R>(IChildVisitor<T, TKey, R> visitor);
}

I've also created these Visitor interfaces:

interface IParentVisitor<T, R> {
    R Visit(IParent<T> parent);
}

interface IChildVisitor<T, TKey, R> : IParentVisitor<T, R> {
    R Visit(IChild<T, TKey> viz);
}

Implementations:

class ParentVisitor<T> : IParentVisitor<T, MyResultClass> {
    MyResultClass Visit(IParent<T> parent) {
      return //...;
    }
}

class ChildVisitor<T, TKey> : IChildVisitor<T, TKey, MyAnotherResultClass> {
    MyAnotherResultClass Visit(IChild<T, TKey> child) {
      return //...;
    }
}

Up to now, everything seems to be right. However, guess this situation:

static void Main() {
    IList<IParent<MyT>> interfaces = new List<IParent<MyT>>();
    interfaces.add(new Parent<MyT>());
    interfaces.add(new Child<MyT, string>());
    interfaces.add(new Child<MyT, int>());
    interfaces.add(new Child<MyT, TimeSpan>());
    //...

    //(!!*!!)
    foreach (IChild<MyT, string> stringChild in interfaces.OfType<IChild<MyT, string>()) {
      ChildVisitor stringChildVisitor = new ChildVisitor<MyT, string>();
      var result = stringChild.Accept(stringChildVisitor);
      //...
    }

    //(!!*!!)
    foreach (IChild<MyT, int> intChild in interfaces.OfType<IChild<MyT, int>()) {
      ChildVisitor intChildVisitor = new ChildVisitor<MyT, int>();
      var result = stringChild.Accept(intChildVisitor);
      //...
    }

    //and so on up to infitiny types in C#...
}

I think it's a non-viable way to get what I want.

What I want to get is to use a ChildVisitor on whichever IChild<T, *>, where * is whichever type. I don't know if I've explained so well.

Something like that:

//(!!*!!)
foreach (IChild<MyT, *> asterisckChild in interfaces.OfType<IChild<MyT, *>()) {
  ChildVisitor asterisckChildVisitor = new ChildVisitor<MyT, *>();
  var result = asterisckChild.Accept(asterisckChildVisitor);
  //...
}

Any ideas?

Aucun commentaire:

Enregistrer un commentaire