-1

New coder here I have the following base interfaces:

public interface ITDXInput
{

}

Which fathers this one:

public interface ITDXInput <TSCContext, TContext, TWaferContainer> : ITDXInput where TContext : IToolContext where TSCContext: ISCContext where TWaferContainer : IWaferContainer
{
    TSCContext SCContext { get; set; }
    TContext ToolContext { get; set; }
    TWaferContainer WaferContainer { get; set; }
}

This interface then fathers this one:

public class CIMTDXInput : ITDXInput<CIMSCContext, CIMToolContext, CIMWaferContainer>
{
    public CIMWaferContainer WaferContainer { get; set; }
    public CIMSCContext SCContext { get; set; }
    public CIMToolContext ToolContext { get; set; }
}

It's members are like so:

public class CIMSCContext : ISCContext
{
    public string PROCESSING_END_TIME { get; set; }
    public string PRODUCT_NAME { get; set; }
    public string QUANTITY_IN { get; set; }
    public string LOT_OWNER { get; set; }
    public string FW_VERSION { get; set; }
 
}

public class CIMToolContext : IToolContext
{
    public string LOT { get; set; }
    public string TDX_MULTI_FILES { get; set; }
    public string PROCESSING_START_TIME { get; set; }
    public string WITHIN_UNIT_AXIS_DIRECTION { get; set; }
}

public class CIMWaferContainer : IWaferContainer
{
    public CIMWaferContext WaferContext = new CIMWaferContext();
    public List<CIMWaferImage> ImageList = new List<CIMWaferImage>();
    public List<CIMWaferDieResults> WaferResultList = new List<CIMWaferDieResults>();

}

But when I try to call the class like so:

public class TDXParser
{
    
    public ITDXInput<ISCContext, IToolContext , IWaferContainer> TDXInput  { get; set; } 

    public IEnumerable<IKlarfDefectList> KlarfDefectList  { get; set; } 

    //some code
    public virtual void WriteKlarf (ITDXInput<ISCContext, IToolContext, IWaferContainer> input, IEnumerable<IKlarfDefectList> defectList) 
    {

        if (File.Exists(TemplatefilePath) && File.Exists(InputfilePath))
        {
            TDXInput = input;
            KlarfDefectList = defectList;
            //some more code
        }
    }
}

The function WriteKlarf is called here:

CIMParser ParserObj = new CIMParser(item, fileName, ParserConfigFilesConstants.CIMTemplateFilePath);
ParserObj.WriteKlarf(input, klarfDefectList);

But Visual studio tells me

Error   CS1503  Argument 1: cannot convert from 'TDXXMLParser.Entity.CIM.CIMTDXInput' to 'TDXXMLParser.Entity.ITDXInput<TDXXMLParser.Entity.ISCContext, TDXXMLParser.Entity.IToolContext, TDXXMLParser.Entity.IWaferContainer>' TDXXMLParser    C:\src\tdx2klarf\TDXXMLParser\TDXXMLParser\Helper\CIM\CIMConversionHelper.cs

I then tried to cast like so:

CIMParser ParserObj = new CIMParser(item, fileName, ParserConfigFilesConstants.CIMTemplateFilePath);
ParserObj.WriteKlarf((ITDXInput<ISCContext, IToolContext, IWaferContainer>)input, klarfDefectList);

But at run time I get the error:

System.InvalidCastException: Unable to cast object of type 'TDXXMLParser.Entity.CIM.CIMTDXInput' to type 'TDXXMLParser.Entity.ITDXInput`3[TDXXMLParser.Entity.ISCContext,TDXXMLParser.Entity.IToolContext,TDXXMLParser.Entity.IWaferContainer]'.

Why is this happening? My CIMTDXInput inherits directly from it's generic interface parent

  • OK, my bad. They looked very similar to me. – DiplomacyNotWar May 27 '22 at 17:19
  • @DiplomacyNotWar I understand. yeah its the same complex data project. Same template just a different specific issue that is holding me back. If you got any insight I am dying to know because I can't for the life of me understand how this shouldn't work. And if you did the downvote please if you can take it off haha. – devn00b1090 May 27 '22 at 17:23
  • I didn't downvote. Although I agree with Kirk (not saying Kirk downvoted) that this possibly isn't the best learning approach, and maybe your example is a bit longer than it needs to be, but other than that it has everything that a question needs (what you're trying to do, what's happening, sufficient error details, and an actual question). – DiplomacyNotWar May 27 '22 at 17:29
  • I can't find a good duplicate and I'm about to go to bed because it's 2:30 am, but I'll try to point you a little way in the right direction. Imagine you have `IPetCarrier where TAnimal: IAnimal`. This requires the implementation of two methods: `bool TryInsertPet(TAnimal animal)` and `bool TryRemovePet(out TAnimal animal)`. You then create a concrete implementation: `LargePetCarrier` and (if this were possible) you assign it to `IPetCarrier`. Accessing `TryInsertPet` and `TryRemovePet` via this interface will mean that the compiler can't be sure that ... – DiplomacyNotWar May 27 '22 at 17:34
  • ... the animal you're trying to insert is actually valid for the `IPetCarrier` implementation. You might call `IPetCarrier myCarrier = new LargePetCarrier(); IAnimal animal = new Hamster(); myCarrier.TryInsertPet(animal);` and then your hamster will escape out the holes that were acceptable when holding a giraffe. It would result in undefined behaviour, and break C#'s static type checking. There are one-way ways around this with the `in` and `out` keywords (contravariance and covariance) but then you can only return or accept (respectively) those types. – DiplomacyNotWar May 27 '22 at 17:38
  • Ultimately the solution will be to rearchitect your code (and what I've said is an explanation, not a solution). If nobody points you in the right direction, @ me tomorrow and I'll write up a proper answer or find a good duplicate. – DiplomacyNotWar May 27 '22 at 17:39

0 Answers0