Eladian
Eladian

Reputation: 958

Generics wildcard or something of the sort

Currently doing an assignment where I have to create a custom user control implemented in C#. I mainly have a java background so I don't know if what I am trying to do is possible in C# - if it isn't, could someone please provide me a link or alternative way I can accomplish the same thing in C#.

public abstract class Graph<T,U>
where T : Configuration.GraphConfiguration
where U : Representatives.GraphRepresentative
{
    public abstract void Draw(Graphics g);
}

public class LineGraph: Graph<LineGraphConfiguration,LineGraphRepresentative>{

    public void draw(Graphics g){

    } 

}

//"Graph" is not valid since the type params <T,U> are not specified..
//However, I cannot supply them since I don't know until runtime what 
//they are. In java just "Graph" or Graph<?,?> would be valid and I  need
//something similar.
public class MyCustomControl: UserControl{
    Graph currentGraph;

    override OnPaint(PaintEventArgs e){
       currentGraph.Draw(e.Graphics);
    }
}

So basically I need a type or some kind of way of holding both a LineGraph and any other type of Graph - for example later a BarGraph - even if the type params are not the same.

Upvotes: 1

Views: 108

Answers (1)

Mat&#237;as Fidemraizer
Mat&#237;as Fidemraizer

Reputation: 64943

Since your code shows that you don't need these generic types to draw the whole graph, I see that you can easily solve the issue defining a non-generic interface:

public interface IGraph
{
     void Draw(Graphics g);
}

...and your abstract class can implement it:

public abstract class Graph<T,U> : IGraph
where T : Configuration.GraphConfiguration
where U : Representatives.GraphRepresentative
{
    public abstract void Draw(Graphics g);
}

...so this means that you can now use IGraph to type your class field:

public class MyCustomControl: UserControl{
    IGraph currentGraph;

    override OnPaint(PaintEventArgs e){
       currentGraph.Draw(e.Graphics);
    }
}

About generics, wildcards...

In .NET, at least, generics were introduced to enforce strong typing as much as possible, and avoid a lot of casts that hurt performance and maintainability. It's not something that can be by-passed.

BTW, C# has covariance and contravariance on interfaces and delegates. I suggest you that you take a look at the following resources:

Upvotes: 8

Related Questions