C# 代码重用(默认接口方法/扩展)

问题描述 投票:0回答:2

我想征求意见。我正在学习 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() 方法吗?我曾尝试使用静态扩展方法,但我想知道是否存在更清洁的方法。好像不太对啊

我知道以下技术可以最大限度地重用代码:

  1. 继承
  2. 静态扩展方法
  3. 默认接口方法

感谢分享您的技术

c# interface code-reuse default-method
2个回答
1
投票

一种方法是将变量键入为接口:

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();

1
投票

您可以将变量的类型保留为接口而不是类。

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
}
© www.soinside.com 2019 - 2024. All rights reserved.