C# 具有部分共享属性、方法的类别。如何避免代码重复?

C# 具有部分共享属性、方法的类别。如何避免代码重复?,c#,interface,multiple-inheritance,C#,Interface,Multiple Inheritance,我有三个类:InputSocket,InternalSocket,OutputSocket。它们都继承自BaseSocket接口,实现了ISocket接口,在这里我有所有类的通用代码,这部分工作正常,我有部分共享代码的问题 InputSocket和InternalSocket与OutputSocket没有共享解析部分 InputSocket和OutputSocket与InternalSocket没有共享GUI部分 我正在寻找一种在InputSocket/InternalSocket和InputS

我有三个类:
InputSocket
InternalSocket
OutputSocket
。它们都继承自
BaseSocket
接口,实现了
ISocket
接口,在这里我有所有类的通用代码,这部分工作正常,我有部分共享代码的问题

InputSocket
InternalSocket
OutputSocket
没有共享解析部分

InputSocket
OutputSocket
InternalSocket
没有共享GUI部分

我正在寻找一种在
InputSocket
/
InternalSocket
InputSocket
/
OutputSocket
之间共享代码公共部分的方法。包含方法和参数的代码。 我已经尝试过使用多个接口,但它没有解决问题,它使它更易于管理。当我为解析部分创建
IParsable
并为输入/输出公共部分创建
IExternal
时,我需要为
InternalSocket
InputSocket
IExternalSocket
OutputSocket
创建
IParsableExternalSocket
。这并没有改变我仍然需要为每种情况实现代码的观点,这会导致代码重复

不幸的是,在c#中,
InputSocket
无法同时从
OutputSocket
InternalSocet
继承


有没有替代方法,复制/粘贴代码或使用一堆if逻辑和null创建一个通用套接字类?

我认为
继承
不是适合您的解决方案。接口中不应该有不打算在继承类中使用/实现的方法。这违反了法律

接口隔离原则(ISP)规定,任何客户端都不应 被迫依赖于它不使用的方法

在您的例子中,这意味着
BaseSocket
不应该是拥有所有“公共”方法的God类。相反,您需要执行一个特定操作的多个接口和实现,例如,在您的案例中,
Parse
Gui

您的不同
Socket
类将获得这些行为/操作的
组合,而不是
inhert
ing。这被称为

面向对象编程中的组合重于继承是 类应实现多态行为和代码的原则 通过它们的组合重用,而不是从基或 父类。这是OOP的一个常用原则,例如 有影响力的书籍设计模式

希望这有帮助。

(你应该用base作为后缀,而不是用base作为前缀)

所以你有:

public class InputSocket : BaseSocket { }
public class InternalSocket : BaseSocket {}
public class OutputSocket : BaseSocket {}
public abstract class BaseSocket : ISocket { }
public interface ISocket {}
InputSocket和InternalSocket与OutputSocket没有共享解析部分

InputSocket和OutputSocket与InternalSocket没有共享GUI部件

使用扩展方法实现:

public static class IParsingSocketExtensions
{
  public static void Parse(this IParsingSocket) {}
}

public static class IGUISOcketExtensions
{
  public static void DoGUI(this IGUISOcket) {}
}
现在你可以

var inps = new InputSocket();
var ints = new InternalSocket();
var outs = new OutputSocket();

inps.Parse() // valid
ints.Parse() // valid
outs.Parse() // invalid

inps.DoGUI() // valid
ints.DoGUI() // invalid
outs.DoGUI() // valid

一般来说,这种情况通常意味着使用继承是错误的。这确实取决于为什么你想让代码> GUI 在你的套接字中,但是最有可能的是,你需要去,或者提取这个功能来分离类,或者使用扩展方法。如果每个Socket类中的所有成员都真正属于那里,那么考虑为每个共享功能创建一个接口。这不会在代码行中保存,但在将套接字传递给特定函数时会有所帮助。另一方面,功能可能不直接属于套接字。也许GUI是它自己的类,某些套接字类型应该引用,或者应该引用套接字。正确建模功能比减少代码行更重要。实现
ParsingProvider
GUIProvider
并使用组合。我将尝试使用组合解决此问题@N-ate GUI是它所属的,问题被简化了,实际上所有这些类都属于GUI,
InputSocket
/
OutputSocket
公共部分只是它们共享的GUI数据,而
InternalSocket
并没有。
public static class IParsingSocketExtensions
{
  public static void Parse(this IParsingSocket) {}
}

public static class IGUISOcketExtensions
{
  public static void DoGUI(this IGUISOcket) {}
}
var inps = new InputSocket();
var ints = new InternalSocket();
var outs = new OutputSocket();

inps.Parse() // valid
ints.Parse() // valid
outs.Parse() // invalid

inps.DoGUI() // valid
ints.DoGUI() // invalid
outs.DoGUI() // valid