Home > Back-end >  One function for two different classes with similar properties
One function for two different classes with similar properties

Time:05-25

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;
}

Try it online

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)
  •  Tags:  
  • c#
  • Related