1

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.

CalvT
  • 3,123
  • 6
  • 37
  • 54
Eladian
  • 958
  • 10
  • 29
  • In Java, generics are syntactic sugar. In C#, they're a compile-time concern :D – Matías Fidemraizer Apr 05 '16 at 08:05
  • 2
    Yep, generics work completely different in C#. In C#, there is no class `Graph`, while in Java, there is *only* the class `Graph`. – Dennis_E Apr 05 '16 at 08:07
  • Haha I figured they weren't the same, unfortunately I figured out a little to late though.. after I had finished the implementations of the classes. Is there an alternative I can use? Little confused as to why it doesn't just deduce to a Graph though, since that makes sense to me. – Eladian Apr 05 '16 at 08:13
  • @Eladian Yes, interfaces. Check my answer! – Matías Fidemraizer Apr 05 '16 at 08:14

1 Answers1

8

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:

Community
  • 1
  • 1
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206