我想征求意见。我正在学习 C#,我一直在努力减少代码重复,我正在努力寻找 C# 中的“最佳实践”。
我正在尝试使用默认接口方法来实现尽可能多的可重用代码,这对于简单示例来说效果很好。
如果类是从具有多种类型的通用接口派生的,我有一个问题,例如
IComplex<T1,T2,T3>
。将对象转换为具有多种类型的通用接口会使代码不可读。我的类派生自更复杂的接口。参考下面的例子。调用方法 Foo() 和 Foo2() 是不可读的:
(complex as IComplex<int, string, decimal>).Foo();
使用新的代码行进行转换是一种选择,但我更愿意只使用“complex.Foo()”而不需要复制已经在“interface IComplex
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 !!!
}
我想像这样直接调用一个方法:
complex.Foo();
无需复制 Foo 代码。
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
}
有什么方法可以在覆盖类 Foo() 方法中重用 IComplex Foo() 方法吗?我曾尝试使用静态扩展方法,但我想知道是否存在更清洁的方法。好像不太对啊
我知道以下技术可以最大限度地重用代码:
感谢分享您的技术
一种方法是将变量键入为接口:
public void DesiredBehaviour()
{
IComplex<int, string, decimal> complex = new Complex<int, string, decimal>();
complex.Foo();
}
如果这是一个常见的要求,甚至是工厂方法:
class Complex<T1, T2, T3> : IComplex<T1, T2, T3>
{
private Complex() { }
static IComplex<T1, T2, T3> Create() => new Complex<T1, T2, T3>();
}
然后你冷写:
var complex = Complex<int, string, decimal>.Create();
complex.Foo();
您可以将变量的类型保留为接口而不是类。
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
}