Hi after failing with inheritance (it got complicated) I stumble onto Generics. I am new to coding in general and C# is my first language.
I have two classes CIMTDXInput, RMTTDXInput which have the same properties but those properties have slightly different members. For those same 3 properties between the two, I want to just check if they are null or not.
So I wrote this:
public static TDX2KlarfResult CheckCIMTDXInput <T> (T input, TDX2KlarfResult result) where T: CIMTDXInput, RMTTDXInput
{
if (input.ToolContext == null)
{
Logger.Warn("Missing Tool Context Skipping the file");
result.errorType = "Warning";
result.errorMessage = "Missing Tool Context";
result.errorSubject = ErrorCategory.MISSING_TOOL_CONTEXT;
result.success = false;
return result;
}
if (input.SCContext == null)
{
Logger.Warn("Missing Context Skipping the file");
result.errorType = "Warning";
result.errorMessage = "Missing Context";
result.errorSubject = ErrorCategory.MISSING_CONTEXT;
result.success = false;
return result;
}
if (input.WaferContainer == null)
{
Logger.Warn("Missing Wafer Container Skipping the file");
result.errorType = "Warning";
result.errorMessage = "Missing Wafer Container";
result.errorSubject = ErrorCategory.MISSING_WAFER_CONTAINER;
result.success = false;
return result;
}
return result;
}
However the code won't compile. I thought you can assign as many classes as you want to the "T"?
Again both classes have ToolContext, SCContext, and WaferContainer. Instead of writing a function for each, I thought it would be elegant to write one for both. I also have additional inputs in the future to add so I'd like to not need to write this function each time
CodePudding user response:
The why
So when you say this:
public void MyMethod<T>(T value) where T: ClassA, ClassB
You're saying that T should be derived from both ClassA
and ClassB
. Now it would work in this scenario:
public class ClassA
{
public int SomeProperty { get; set; }
}
public class ClassB : ClassA
{
}
public class ClassC : ClassB
{
}
MyMethod<ClassB>(classBValue); // ClassB is a ClassB and is derived from ClassA
MyMethod<ClassC>(classCValue); // ClassC is derived from ClassB, and is indirectly derived from ClassA
But this won't work:
public class ClassA
{
public int SomeProperty { get; set; }
}
public class ClassB
{
public int SomeProperty { get; set; }
}
Because it requires a ClassC that looks like this:
public class ClassC : ClassA, ClassB
{
}
And this could will cause a compile time error because C# doesn't support multiple inheritance. That is to say that, while you can have a class derived from a class that itself is derived from another class, you can't create a class that directly derives from two classes.
The solution
What you can do is declare an interface:
public interface ISomeInterface
{
int SomeProperty { get; set; }
}
And have both the classes implement it:
public class ClassA : ISomeInterface
{
public int SomeProperty { get; set; }
}
public class ClassB : ISomeInterface
{
public int SomeProperty { get; set; }
}
Then if we change our method signature to require that the class implements our interface:
public void MyMethod<T>(T value) where T: ISomeInterface
Then within the method we can access the SomeProperty
property of T
:
public void MyMethod<T>(T value) where T: ISomeInterface
{
value.SomeProperty *= 2;
}
CodePudding user response:
you need to use an interface
public interface IInput
{
public string ToolContext {get;set;}
public string SCContext {get;set;}
public string WaferContainer {get;set;}
}
public class CIMTDXInput:IInput
{
public string ToolContext {get;set;}
public string SCContext {get;set;}
public string WaferContainer {get;set;}
.... another properties
}
public class RMTTDXInput:IInput
{
public string ToolContext {get;set;}
public string SCContext {get;set;}
public string WaferContainer {get;set;}
.... another properties
}
and your method should be
public static TDX2KlarfResult CheckCIMTDXInput<T>(T input, TDX2KlarfResult result) where T : IInput
or you can get without a generic in this case , would be enough
public static TDX2KlarfResult CheckCIMTDXInput(IInput input, TDX2KlarfResult result)