1

I have the following abstract class:

public abstract class PinkBoxMasksDataAbstract
{
    public string PinkBoxText { get; set; }
}

and 2 subclasses:

public class PinkBoxMasksDataNoOverlay : PinkBoxMasksDataAbstract
{
}

public class PinkBoxMasksDataOverlay : PinkBoxMasksDataAbstract
{
    public int PinkBoxLeft { get; set; }
    public int PinkBoxBoxTop { get; set; }
    public int PinkBoxHeight { get; set; }
    public int PinkBoxWidth { get; set; }
}

then I have another class, which has PinkBoxMasksDataAbstract class as parameter:

public class ZonalMatchResult<T> where T : PinkBoxMasksDataAbstract
{
    public decimal Confidence { get; set; }
    public int GreenBoxLeft { get; set; }
    public int GreenBoxTop { get; set; }
    public int GreenBoxHeight { get; set; }
    public int GreenBoxWidth { get; set; }

    public List<T> PinkBoxMasksData { get; set; }
}

public class ZonalResult<T> where T : PinkBoxMasksDataAbstract
{
    public int ExitCode { get; set; }
    public string ErrorMessage { get; set; }
    public int NumberOfGreenBoxMatches { get; set; }
    public int NumberOfPinkBoxExtractFrames { get; set; }
    public int ProcessingTime { get; set; }
    public bool HasOverlay { get; set; }

    public List<ZonalMatchResult<T>> MatchResults { get; set; }
}

now I want to create this class this way:

            ZonalResult<PinkBoxMasksDataAbstract> zonalResult;
            if (isOverlayRequired)
                zonalResult = new ZonalResult<PinkBoxMasksDataOverlay>();
            else
                zonalResult  = new ZonalResult<PinkBoxMasksDataNoOverlay>();

but I get an error:

Cannot implicitly convert type 'Domain.ZonalResult<Domain.PinkBoxMasksDataOverlay>' to 'Domain.ZonalResult<Domain.PinkBoxMasksDataAbstract>'

Why it happens if PinkBoxMasksDataOverlay is subclass of PinkBoxMasksDataAbstract? How to fix?

Oleg Sh
  • 8,496
  • 17
  • 89
  • 159
  • Create a `ZonalMatchResultBase` class not generic and inherit `ZonalMatchResult` from that, then you can use the base type to store any generic instance. – Gusman May 30 '17 at 20:13
  • `ZonalMatchResult` and `ZonalMatchResult` have no common base class other than `object`. The inheritance relationship of the type parameters is of no consequence here; if they're different, they're different. – 15ee8f99-57ff-4f92-890c-b56153 May 30 '17 at 20:14
  • @Gusman, I have a deep child classes. Really ZonalMatchResult only is chain of nested classes – Oleg Sh May 30 '17 at 20:24
  • I can't see that on the code example, if the example is wrong then update it with the correct data. – Gusman May 30 '17 at 20:26
  • Your question is just yet another example of the all-too-commonly asked _"why even though my type parameter T1 inherits another type parameter T2, my generic type G doesn't inherit generic type G"_. See marked duplicate for one of the earliest examples. There are many, and they all come down to the same thing: the inheritance relationship you want is valid only in very specific conditions, and your code hasn't satisfied those conditions. Without those conditions, unsafe behavior could occur dealing with instances of your generic types. – Peter Duniho May 30 '17 at 23:11

1 Answers1

1

ZonalMatchResult does not inherit from PinkBoxMasksDataAbstract, only its type parameter does. That is the reason, you get this error.

You could specificaly set the data this way (of course it may not be abstract in this case):

ZonalMatchResult<PinkBoxMasksDataAbstract> r = new ZonalMatchResult<PinkBoxMasksDataAbstract>;
if (isOverlayRequired)
    r.PinkBoxMasksData = new PinkBoxMasksDataOverlay();
else
    r.PinkBoxMasksData = new PinkBoxMasksDataNoOverlay();

However, why not simple have PinkBoxMasksData class which has a Overlay property. If this property is null, you do not have an Overlay.

public class Overlay
{
    public int PinkBoxLeft { get; set; }
    public int PinkBoxBoxTop { get; set; }
    public int PinkBoxHeight { get; set; }
    public int PinkBoxWidth { get; set; }
}

public class Mask
{
    public string PinkBoxText { get; set; }
    public Overlay Overlay { get; set; }
}


var mask = new Mask();
if (isOverlayRequired)
{
    mask.Overlay = new Overlay();
}

For Interfaces, there is also the option of covariance, but this is not possible for classes. So no, I don't think there is a way.

Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
  • problem is to generate json file. It creates nested structure like: "PinkBoxText": "75 reviews\r\n", "PinkBoxCoordinates": { "PinkBoxLeft": 179, "PinkBoxBoxTop": 532, "PinkBoxHeight": 20, "PinkBoxWidth": 65 }, but I need without PinkBoxCoordinates property – Oleg Sh May 31 '17 at 08:17