Reputation: 141
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
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