For example I have the following classes:
1.
class MyClass1
{
public MyClass1 Method()
{
...
return new MyClass1();
}
}
class MyClass2
{
public MyClass2 Method()
{
...
return new MyClass2();
}
}
The methods have the same bodies that's why I want to extract the code and re-use.
2.
abstract class MyClass
{
protected void Method()
{
...
}
}
class MyClass1 : MyClass
{
public MyClass1 Method()
{
base.Method();
return new MyClass1();
}
}
class MyClass2 : MyClass
{
public MyClass2 Method()
{
base.Method();
return new MyClass2();
}
}
However since there are a lot of such methods it will be better to move the methods into the base class MyClass
at all:
3.
abstract class MyClass<T>: where T : MyClass<T>
{
protected abstract T Create();
public T Method()
{
...
return Create();
}
}
class MyClass1 : MyClass<MyClass1>
{
protected override MyClass1 Create() => new MyClass1();
}
class MyClass2 : MyClass<MyClass2>
{
protected override MyClass2 Create() => new MyClass2();
}
It works fine but the contract looks too weird. Of course, I can extract something like IMyInterface
and return it instead of the class. However I have to preserve the original contract because it contains specific methods as well.
Upd: So, the weird thing is in bold - class MyClass1: MyClass<MyClass1>
This is the usual so-called self-type problem (you have Method()
should return the same type as the object on which it was called). Your solution #3 looks a lot like F-bounded quantification. However, this is C#, not Java, so we can do a bit better using an extension class.
You can make sure those methods only get called on subclasses of MyClass
by adding a where T : MyClass
bound on T
.
// Put all your shared methods in generic classes in here.
public static class MyMethods
{
public static T Method<T>(this T x) where T : MyClass
{
...
}
}
Your classes don't change much, except they won't need to mention Method
(or the other shared methods) at all.
public abstract class MyClass
{
...
}
public class MyClass1 : MyClass
{
...
}
public class MyClass2 : MyClass
{
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With