Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中显示继承接口实现的最佳方式是什么?_C#_Interface - Fatal编程技术网

在C#中显示继承接口实现的最佳方式是什么?

在C#中显示继承接口实现的最佳方式是什么?,c#,interface,C#,Interface,给定以下接口: interface IFoo { void Foo(); } interface IBar : IFoo { void Bar(); } 指示给定类实现IBar的最佳方式是什么 方法A: 这似乎更简单、更清晰,但并不表示实现实现IFoo 方法B: 这似乎是最有用的信息,但额外的信息真的是必要的吗?我选择A。您可以看到需要在类本身中实现哪些方法,IDE中的导航工具将帮助您完成其余的工作 B在进行任何重构时都无法维护(例如,如果替换IBar或将其拆分为2会发生什么

给定以下接口:

interface IFoo
{
    void Foo();
}

interface IBar : IFoo
{
    void Bar();
}
指示给定类实现IBar的最佳方式是什么

方法A: 这似乎更简单、更清晰,但并不表示
实现
实现
IFoo

方法B:
这似乎是最有用的信息,但额外的信息真的是必要的吗?

我选择A。您可以看到需要在类本身中实现哪些方法,IDE中的导航工具将帮助您完成其余的工作


B在进行任何重构时都无法维护(例如,如果替换IBar或将其拆分为2会发生什么?

编译器不需要额外的信息,但它可能会对代码的读者有所帮助,因为读者不必知道
IBar
扩展了
IFoo
。框架中的一个例子是
List
,它实现了
,我认为方法A足够清晰,因为(无论如何在VS.NET中)您可以非常快速地确定IBar实现了IFoo

就个人而言,我同意前者。对于后者,假设您在这种情况下拥有一组派生类:

class DerivedA : Implementation, IBar, IFoo { ... }
class DerivedB : Implementation, IBar, IFoo { ... }
class DerivedC : Implementation, IBar, IFoo { ... }
class DerivedD : Implementation, IBar, IFoo { ... }
然后,您对
实现的需求发生了变化,因此现在需要实现另一个接口,如
IBaz
(只要它提供非抽象实现,就不必影响任何派生类),然后您有两个选项:

  • 保留所有派生类定义而不显式声明新接口信息,在这种情况下,根据标准,类定义现在是不正确的,如果人们希望始终遵循标准,则可能会产生误导

  • 查找所有派生类及其派生类,并修复它们的声明。这需要时间,有点容易出错,而且很难完全完成,并且会将单个文件更改转换为多文件签入


  • 这两种选择都没有吸引力,所以我会选择不会让你陷入任何一种情况的选择。只需声明最派生的接口。

    除了可读性和中的差异(参见Kathleen Dollard的评论),数据绑定的情况需要(B)。我忘记了细节(我会编辑,除非有人击败我…)


    我认为这就是.NET Framework集合显式实现其派生接口的原因。

    您已经在
    IBar
    中实现了
    IFoo
    ,这意味着您甚至不需要指定具体的实现类实现
    IFoo
    ;CLR可以推断,如果您在组件上使用Reflector,您会看到它指定
    实现
    实现
    IFoo
    IBar
    ,即使您使用方法A


    方法A就是这样。

    我之所以选择方法A,是因为在类定义的派生列表中列出一个接口意味着您在该类中提供了一个实现。如果您不打算提供IFoo的替代实现,那么我不会将其包括在列表中,除非您需要它作为一个简单的“标记接口”。然而,即使这样,在运行时,“is”操作符(返回true或false)或“as”关键字(返回对象或null)也会告诉您是否可以将对象强制转换为IFoo。

    @tvanfosson:框架这样做的原因是否与数据绑定有关?@Mitch-是的,如果您显式实现了任何接口,这也是必要的。如果我有一个接口继承层次结构,我可能会列出接口。为什么让读者自己猜测实现了哪些接口呢?当从类派生时,我不会担心这一点。不过,在接口的情况下,您通常不希望继承,而将两者都列出会让您更清楚。
    class Implementation : IBar, IFoo { ... }
    
    class DerivedA : Implementation, IBar, IFoo { ... }
    class DerivedB : Implementation, IBar, IFoo { ... }
    class DerivedC : Implementation, IBar, IFoo { ... }
    class DerivedD : Implementation, IBar, IFoo { ... }