Datboydozy
Datboydozy

Reputation: 141

Is it Possible to Add A new property to Existing Interface When You Call the Interface?

Let me preface by saying I am new to coding and C# is my first language. Just getting used to inheritance and interfaces. Consider this example:

public interface ITDXInput
    {
        ISCContext SCContext { get; set; }
        IToolContext ToolContext { get; set; }
    }

Which calls this Inteface:

public interface IToolContext
    {
        string LOT { get; set; }
        string TDX_MULTI_FILES { get; set; }
        string PROCESSING_START_TIME { get; set; }
        string PROCESSING_END_TIME { get; set; }
        string MEDIA_ORIGIN_LOCATION { get; set; }
        string MEDIA_ORIENTATION { get; set; }
        string MEDIA_AXIS_DIRECTION { get; set; }
    }

ITDXInput is referenced:

public class CIMTDXInput : ITDXInput
    {
        public ISCContext SCContext { get; set; }
        public ITestToolContext ToolContext { get; set; }
    }

ItoolContext is referenced in two places:

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 PROCESSING_END_TIME { get; set; }
        public string RECIPE_NAME { get; set; }
        public string TOOL_IMAGE_PATH { get; set; }
        public string TOOL_SOFTWARE_VERSION { get; set; }
        public string MEDIA_ORIGIN_LOCATION { get; set; }
        public string MEDIA_ORIENTATION { get; set; }
        public string MEDIA_AXIS_DIRECTION { get; set; }
        public string WITHIN_UNIT_ORIGIN_LOCATION { get; set; }
        public string WITHIN_UNIT_AXIS_DIRECTION { get; set; }
    }

And here:

public class RMTToolContext : IToolContext
    {
        public string LOT { get; set; }
        public string TDX_MULTI_FILES { get; set; }
        public string PROCESSING_START_TIME { get; set; }
        public string PROCESSING_END_TIME { get; set; }
        public string MEDIA_ORIGIN_LOCATION { get; set; }
        public string MEDIA_ORIENTATION { get; set; }
        public string MEDIA_AXIS_DIRECTION { get; set; }
    }

Because of this when I try to run

Someclass{

public CIMTDXInput CimInput 
        {
            get { return (CIMTDXInput)base.TDXInput; }
        
        } 

protected override void PopulateValueMap()
        {
            ValueMap["#DATA.TOOL_CONTEXT.RECIPE_NAME#"] = CimInput.ToolContext.RECIPE_NAME;
            ValueMap["#DATA.TOOL_CONTEXT.TOOL_SOFTWARE_VERSION#"] = CimInput.ToolContext.TOOL_SOFTWARE_VERSION;

        }

}

It tells me IToolContext does not contain a definition for RECIPE_NAME and TOOL_SOFTWARE_VERSION

I was wondering if there is a way to modify IToolContext when I call it CIMTDXInput? If there is a way to extend ItoolContext for just that CIMTDXInput class?

This way I don't need to declare those additional fields for the root IToolContext Interface because the other tool RMTToolContext doesn't need those extra properties of RECIPE_NAME and TOOL_SOFTWARE_VERSION?

Unless there is a better way to handle these extra fields that CIMToolContext needs?

Upvotes: 0

Views: 239

Answers (1)

John Paul R
John Paul R

Reputation: 707

I was wondering if there is a way to modify IToolContext when I call it CIMTDXInput? If there is a way to extend ItoolContext for just that CIMTDXInput class?

Not exactly. You cannot modify the type definitions. Assuming you know for sure that the IToolContext you are dealing with is a CIMTDXInput, you can type cast it to the CIMTDXInput type. (This means it will be treated as a CIMTDXInput instead of a IToolContext.

Be warned, however, if you attempt to cast this IToolContext to CIMToolContext and it is not actually an instance of the CIMToolContext class, your program will throw an exception (error).


A safer way to do the same thing is to use the is operator to check that the IToolContext is actually a CIMToolContext instance.

This can be done as follows:

if (CimInput.ToolContext is CIMToolContext) {
    ValueMap["#DATA.TOOL_CONTEXT.TOOL_SOFTWARE_VERSION#"] = (CIMToolContext)CimInput.ToolContext.TOOL_SOFTWARE_VERSION;
}

or, slightly more concisely:

if (CimInput.ToolContext is CIMToolContext cimToolContext) {
    ValueMap["#DATA.TOOL_CONTEXT.TOOL_SOFTWARE_VERSION#"] = cimToolContext.TOOL_SOFTWARE_VERSION;
}

As a general rule, casting should be a last-ish resort. If possible, you should design your types so that it is unnecessary.


Unless there is a better way to handle these extra fields that CIMToolContext needs?

I think for your case there might be. In your case, I think I might lean towards the use of generics for a cleaner solution but this is a slightly more complex idea.

This would, however, allow you to do all of this without any typecasts.

public interface ITDXInput<TContext>
{
    ISCContext SCContext { get; set; }
    TContext ToolContext { get; set; }
}

public class CIMTDXInput : ITDXInput<CIMToolContext>
{
    public ISCContext SCContext { get; set; }
    public CIMToolContext ToolContext { get; set; }
}

public class SomeClass
{

    public CIMTDXInput CimInput 
    {
        get { return base.TDXInput; }
    } 

    protected override void PopulateValueMap()
    {
        ValueMap["#DATA.TOOL_CONTEXT.RECIPE_NAME#"] = CimInput.ToolContext.RECIPE_NAME;
        ValueMap["#DATA.TOOL_CONTEXT.TOOL_SOFTWARE_VERSION#"] = CimInput.ToolContext.TOOL_SOFTWARE_VERSION;
    }

}

Upvotes: 1

Related Questions