2 回答
TA贡献1946条经验 获得超3个赞
您应该从 MSDN 上阅读有关Interface Design
https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface
✓ 如果您需要一些通用 API 由一组类型(包括值类型)支持,请务必定义一个接口。
✓ 如果您需要在已经从其他类型继承的类型上支持其功能,请考虑定义一个接口。
X 避免使用标记接口(没有成员的接口)。
如果需要将类标记为具有特定特征(标记),通常使用自定义属性而不是接口。
✓ 务必提供至少一种类型,它是接口的实现。
这样做有助于验证接口的设计。例如,List 是 IList 接口的实现。
✓ 务必提供至少一个使用您定义的每个接口的 API(一种将接口作为参数的方法或类型化为接口的属性)。
这样做有助于验证界面设计。例如,List.Sort 使用 System.Collections.Generic.IComparer 接口。
X 不要将成员添加到以前发布的接口中。
更多参考:空接口空接口代码有味道吗?
标记界面 标记界面 的用途是什么?
TA贡献1921条经验 获得超9个赞
这称为“标记界面”。有时它们被用来表示一个类是用于特定目的的。这不是一种理想的做法。
虽然我使用了标记界面,但这里是它们造成的问题的说明。假设我有一个List<ICube>. 也许我将它作为方法参数接收。
public interface ICube {} // It's empty!
public void DoSomethingWithTheseCubes(List<ICube> cubes)
{
foreach(var cube in cubes)
{
// what do I do with this cube?
}
}
你可以看到我卡在哪里。ICube只是一个标记接口,所以它没有自己的方法或属性。我对它无能为力。这可能会导致我将每个立方体转换为其他类型,这样我就可以用它做一些事情。
public void DoSomethingWithTheseCubes(List<ICube> cubes)
{
foreach(var cube in cubes)
{
(SomeOtherType)cube.DoSomething();
}
}
但是如果我转换它,我会引发运行时错误,因为我可能不确定每个对象的实际运行时类型是什么。如果我知道运行时类型是什么,那么我应该这样做:
public void DoSomethingWithTheseCubes(List<SomeOtherType> things)
{
foreach(var thing in things)
{
thing.DoSomething();
}
}
我们不能绝对肯定会遇到这个问题,但使用标记界面会引起它。它正在将接口用于其预期目的之外的其他用途。它更像是一个属性甚至是评论。
接口有两种协同工作的用途:首先,它描述类实现的成员。其次,它允许我们将实现接口的类转换为该接口。标记接口两者都不做。它们允许我们将对象转换为没有成员的类型。这充其量是无用的,而在最坏的情况下它是有害的,因为它会导致更多有问题的演员表。
- 2 回答
- 0 关注
- 81 浏览
添加回答
举报