Using C#, I have a function that looks like this:
void Function(NotMyClass param1, INotMyInterface1 param2)
{
param2.Dostuff(param1);
{
I have another function that has the exact same body but uses a different interface for the second parameter, like this:
void Function(NotMyClass param1, INotMyInterface2 param2)
{
param2.Dostuff(param1);
{
I would like to write something like this in order to not repeat code:
void Function<T>(NotMyClass param1, T param2)
{
param2.Dostuff(param1);
{
and be able to pass either argument.
The classes that these objects belong to are restricted and I cannot access them in the function, only the interface. I have looked into parameter constraints but it does not seem to be working. Is it possible to do what I am trying to do there? If so how?
Edit: I updated the functions to match more closely what is happening. The DoStuff() function is common to both interfaces. I don't have access to modify either the classes that implement the interfaces, nor the interfaces themselves. The classes themselves are restricted and I cannot use them at all in the code. The interfaces seem to be being used more like a type.
CodePudding user response:
If you want to make sure that T actually inherits from something useful, make your Interface1 and Interface2 derive from a base interface and then format as such:
void Function<T>(MyClass param1, T param2) where T : IBaseInterface { }
Put your common logic in IBaseInterface and any uncommon logic in Interface1 and Interface2. If there is no common logic, while it is acceptable to make interfaces with no contractual methods inside of them, it may be a case where you should rethink why T should be shared between the two.
CodePudding user response:
Does the rest of your example looks something like;
Dostuff(MyClass param1, Interface1 param2){...}
Dostuff(MyClass param1, Interface2 param2){...}
In which case generics won't help very much. As there is no simple way to pick a method overload based on the runtime type of a variable.
At best you could ask the caller to pass in a delegate, but that's only useful if your function has a larger amount of complexity than the example in your question.
void Function<T>(MyClass param1, T param2, Action<MyClass, T> stuff) {
stuff(param1, param2);
}
void Function(MyClass param1, Interface1 param2)
=> Function(param1, param2, DoStuff;
void Function(MyClass param1, Interface2 param2)
=> Function(param1, param2, DoStuff;