Reputation: 1029
I would like to ask for an advise. I am learning C# and I am always trying to reduce code duplication and I am struggling to find "best practice" in C#.
I am trying to use Default interface methods to implement as much reusable code as possible, which works fine for simple examples.
I have an issue if class is derived from generic interfaces with several types e.g. IComplex<T1,T2,T3>
. Casting object to Generic Interface with many types makes code unreadable. My class is derived from more such complex Interfaces. Refer to the example below. Calling a method Foo() and Foo2() is unreadable:
(complex as IComplex<int, string, decimal>).Foo();
Using a new line of code for casting is an option, but I would prefer to just use 'complex.Foo()' without the need to duplicate the code already written in `interface IComplex<T1,T2,T3>'.
interface IComplex<T1,T2,T3>
{
T1 Property1 { get; set; }
T2 Property2 { get; set; }
T3 Property3 { get; set; }
void Foo()
{
// Default method
// Do some complicated stuff with Property1-3
}
}
interface IOtherInterface<T1,T2,T3>
{
void Foo2()
{
// Default method
// Do some complicated stuff
}
}
public class Complex<T1, T2, T3> : IComplex<T1, T2, T3>, IOtherInterface<T1, T2, T3>
{
public T1 Property1 { get; set; }
public T2 Property2 { get; set; }
public T3 Property3 { get; set; }
}
public void ComplexExample()
{
Complex<int, string, decimal> complex = new Complex<int, string, decimal>();
(complex as IComplex<int, string, decimal>).Foo(); // <<<< This is not easily Readable !!!
(complex as IOtherInterface<int, string, decimal>).Foo2(); // <<<< This is not easily either Readable !!!
}
I would like to call a method directly like: complex.Foo();
without the need to replicate the Foo code.
public void DesiredBehaviour()
{
Complex<int, string, decimal> complex = new Complex<int, string, decimal>();
complex.Foo(); // This would be nice, but it is is compile error
complex.Foo2(); // This would be nice, but it is is compile error
}
Is there any way to reuse the IComplex Foo() method in the override class Foo() method ? I have tried to use static extension methods, but I wonder if something cleaner exists. It seems not right.
I am aware of following techniques to maximise code reuse:
Thanks for sharing your techniques
Upvotes: 3
Views: 489
Reputation: 12705
you can keep the type of the variable as the interface and not as the class.
public void DesiredBehaviour()
{
IComplex<int, string, decimal> complex = new Complex<int, string, decimal>();
complex.Foo(); // This would be nice, but it is is compile error
}
Upvotes: 1
Reputation: 20373
One way would be to type the variable as the interface:
public void DesiredBehaviour()
{
IComplex<int, string, decimal> complex = new Complex<int, string, decimal>();
complex.Foo();
}
Or even a factory method if this is a common requirement:
class Complex<T1, T2, T3> : IComplex<T1, T2, T3>
{
private Complex() { }
static IComplex<T1, T2, T3> Create() => new Complex<T1, T2, T3>();
}
Then you cold write:
var complex = Complex<int, string, decimal>.Create();
complex.Foo();
Upvotes: 1