我有一些接口需要一些简单的实现,但我有少数,例如(不是实际代码,只是示例)
interface ISelectable
{
public bool IsSelected;
public void Select();
}
public class Selectable : ISelectable
{
public bool IsSelected {get;set}
public void Select()=> IsSelected = true;
}
然后我可能有IStorable
,它允许在数据库中存储内容,如:
public interface IStorable
{
public void Store();
...
}
public class Storable : IStorable
{
private stuff...
public void Store() { storing code }
}
问题是:
我
- 为
IStorable
但不为ISelectable
的元素, - 元素是
ISelectable
而不是IStorable
, - 和元素。
实际上……我有更多这样的课。所以这些组合发展得很快。
据我所知,共享代码的唯一方法是让一个基类实现接口,然后你的类继承这个基类。如:
public class GameCard : Selectable { ....
但是这将意味着拥有一个继承Selectable
代码和可存储代码的类的唯一方法是有一个基类同时做这两件事,比如public class StorableAndSelectable: IStorable, ISelectable
。但是这没有意义,特别是当你想要有不同的存储方法时…
让你的类共享它实现的接口的实现代码的正确方法是什么?在一个文件中实现它们中的每一个,并提供这个"文件";给所有需要它的班级?
我会考虑继承是否是这种简单属性的正确方法。有一些可能的替代方案。使用继承来包含功能称为实现继承,通常是不受欢迎的。对于这样简单的东西,它几乎没有什么好处,而对于更复杂的逻辑,它将派生类与基类紧密地联系在一起。
要存储对象,我可能会建议使用存储库模式,这样您就不需要特殊的接口。
要处理诸如对象是否被选中之类的事情,最简单的选择可能只是在接口中有一个可设置的属性:bool IsSelected {get;set;}
。这是所有派生类都可以轻松实现的,仅实现该接口没有真正的优势,至少在测试/虚拟对象之外没有。
在某些情况下,您可以使用Func<T, bool>
来描述如何确定是否选择了某个任意类型。在某些情况下,使用组合可能是有用的,即使用一个单独的类来描述选择,并让你的游戏对象包含该类的属性。
从c# 8.0开始,您可以在接口定义中实现默认方法
interface IA
{
void M() { WriteLine("IA.M"); }
}
class C : IA { } // OK
IA i = new C();
i.M(); // prints "IA.M"
8.0 https://learn.microsoft.com/en - us/dotnet/csharp/language reference/proposals/csharp - -/-默认接口方法
根据你的类,你可以这样做
interface ISelectable
{
public bool IsSelected;
public void Select() => IsSelected = true;
}