0

I have a problem similar to this thread but mine is a bit different.

I want to create something like this

public abstract class Plot
{
    protected GameObject plotModel;
    protected IDataPoint[] data;
    protected GameObject[] plotModelInstances;

    protected Plot<TDataPoint>(TDataPoint[] data, GameObject plotModel, Vector2 plotCenter = default) where TDataPoint : IDataPoint
    {
        this.data = data;
        this.plotModel = plotModel;
        plotModelInstances = new GameObject[data.Length];
        this.plotCenter = plotCenter;
    }
}

A base class that takes in a data array of a generic type which implements the interface IDataPoint. The child class is now supposed to be constructed with a data array of a struct that implements this interface

public BarPlot(BarDataPoint[] data, GameObject plotModel, float barWidth = 1, float barHeight = 1, Vector2  = default) : base(data, plotModel, plotCenter) 
    {
        this.barWidth = barWidth;
        this.barHeight = barHeight; 
    }

One answer in the thread linked above said that constructors can't use generics in C# and suggested a combination of a generic class and a static class. However, I don't want a whole class but only one parameter to be generic. Any ideas how to achieve that?

4
  • 2
    Why does the constructor need to be generic? data is simply setting a field, so what's wrong with: protected Plot(IDataPoint[] data, GameObject plotModel, Vector2 plotCenter = default)? Commented Jul 22, 2020 at 12:15
  • 1
    The constructor itself can't use generics directly. Either you make the abstract class generic or you use an array of IDataPoint in the constructor. Commented Jul 22, 2020 at 12:18
  • because if I try to pass BarDataPoint[] to the Plot constructor it says it can't convert BarDataPoint[] to IDataPoint[]. But I also don't want to pass in IDataPoint[] into the BarPlot constructor since this wouldn't be the correct type Commented Jul 22, 2020 at 12:20
  • Does BarDataPoint implement IDataPoint? If it does, then there shouldn't be a problem. If it does not, generics isn't going to help anyway. Commented Jul 22, 2020 at 12:24

1 Answer 1

5

Your best option is probably something like this:

public abstract class Plot<TDataPoint>  where TDataPoint : IDataPoint
{
    protected GameObject plotModel;
    protected TDataPoint[] data; // Note: Changed IDatePoint[] to TDataPoint[]!
    protected GameObject[] plotModelInstances;

    // Note: Changed IDatePoint[] to TDataPoint[]!
    protected Plot(TDataPoint[] data, GameObject plotModel, Vector2 plotCenter = default)
    {
        this.data = data;
        this.plotModel = plotModel;
        plotModelInstances = new GameObject[data.Length];
        this.plotCenter = plotCenter;
    }
}

And then, in the child class:

public class BarPlot : Plot<BarDataPoint>
{

    public BarPlot(BarDataPoint[] data, GameObject plotModel, float barWidth = 1, float barHeight = 1, Vector2 plotCenter = default) 
        : base(data, plotModel, plotCenter) 
    {
        this.barWidth = barWidth;
        this.barHeight = barHeight; 
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Glad to help :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.