Generics and Inheritance question

K, after an hour or so of playing with generics I've already hit my first snag...

How do you declare an abstract property to return an instance of a template class that will be instantiated with the type of the derived class (what a mouthful!) i.e.:


public abstract class Node {

    public abstract NodeList< > ConnectedNodes {get;}

}

public class GraphNode : Node {

    private NodeList< > _connectedNodes;

    public NodeList< > ConnectedNodes

    {

        get

        {

            return _connectedNodes;

        }

    }

}


 



In the case above, I want the NodeList to be NodeList<GraphNode> (or whatever the name of any derived classes would be). I guess what I'm asking is there some sort of "this" keyword for templates... because I don't know if this works or not, but I don't want to have to do this:


public abstract class Node<NodeType> where NodeType : Node {

    public abstract NodeList<NodeType> ConnectedNodes {get;}

}

public class GraphNode<NodeType> : Node<NodeType> {

    private NodeList<NodeType> _connectedNodes;

    public NodeList<NodeType> ConnectedNodes

    {

        get

        {

            return _connectedNodes;

        }

    }

}


 



Because in client code, that means I'd have to initialize a GraphNode like this:


GraphNode<GraphNode> node = new GraphNode<GraphNode>();


 



which seems unnecessarily redundant and somewhat odd.

-Brian



Answer this question

Generics and Inheritance question

  • WillianNG

    Solved this on myself!! but i'll let it here as example...

    After some further research i still haven't found a solution, but i have found a similar example.

    i have an OList that derives from a generic sortedList. The value is of type MyObject (which is no problem) and i want the Key to be a normal int. But since int is a structure i can't say "where K:Int32.
    Not really a problem so far but when i want to call the method IndexOfKey i have a problem: i get an error saying:

    Error 1 Argument '1': cannot convert from 'int' to 'K'  



    public class OList<K,V>:SortedList<K,V>
    where V:MyObject  
    where K:Int32               /*but this line won't compile.*/
    {
       constructor,...
       
       
       public int myFunction(int key)
       {
          int temp=this.IndexOfKey(key);    /*i get the error on this line*/

          /* do some calculations on temp */
                                         
          return temp;   
      }
     
    }

     


    solution
    When dealing with inheritance and generics, you can put the specific type in the call of the base class (in this case the sorted list). The where statement are no longer needed in this specific Case.

    solution code


    public class OList<K,V>:SortedList<int,MyObject>
    {
       constructor,...
         
       public int myFunction(int key)
       {
          int temp=this.IndexOfKey(key);   
          /* do some calculations on temp */
                                         
          return temp;   
      }
    }


     




    Another problem i have is that in my previous code i used a normal SortedList (cause generics didn't exist) and it had a method GetByindex, to get the value at a specific index in the list, they seem to have forgot it in the generic SortedList :)


  • bcbs_tony

    Solved

    I have a class FList <T>: OList
    a class F
    and some classes F1, F2,... Which all derive from F (  class F1:F ), in turn F derives from O , i only declare FList with parameter F1 or F2 or ... 
    i have a function that has as a parameter an FList and in the declaration of my function i write


    public int  MyFunction (FList<F> myFList);
    {
       do some calculations on myFList;
       return a value
    }  

     

    So in this function i want to do the same for every deriverd class of F
    This works fine but the problem occurs when i make the OList a generic type to:


    class FList<T>:OList<T>

     

    if i do this is get an error when i call MyFunction


    FList<F1> flist=new FList<F1>(); 
    int i= MyFunction(flist);

     

    Compile error
    Argument '1': cannot convert from 'FList<F1>' to FList<F>' 

    Solution

    public int  MyFunction<T> (FList<T> myFList) where T:F
    {
       do some calculations on myFList;
       return a value
    }  

     


  • dragon_ballz96

    Try...



    public abstract class Node<T>
       where T : Node<T>
    {
       public abstract NodeList<T> ConnectedNodes { get; }
    }

    public class GraphNode : Node<GraphNode>
    {
       private NodeList<GraphNode> _connectedNodes;

       public override NodeList<GraphNode> ConnectedNodes
       {
          get{ return _connectedNodes; }
       }
    }

     


    Client code...

    GraphNode node = new GraphNode();

  • IMstuck

    Question...  Are you using the template types K and V anywhere in the code for OList  

    If not, change your declaration to "public class OList : SortedList< int, MyObject>"


  • &amp;#42;jsd&amp;#42;

    I'm not sure I can follow your description of the problem.  For example, you say "when I call MyFunction  int i = MyFunction(F1)" I'm confused.  What exactly is "F1"   F1 is an implementation of F isn't it   MyFunction takes an FList, not an F.  Can you post a small complete code sample that duplicates your problem

  • Generics and Inheritance question