C# 我应该包括继承链中的所有接口吗?
如果我有两个接口:C# 我应该包括继承链中的所有接口吗?,c#,inheritance,interface,C#,Inheritance,Interface,如果我有两个接口: interface IGrandparent { void DoSomething(); } interface IParent : IGrandparent { void DoSomethingElse(); } 然后有两种实现: //only includes last interface from the inheritance chain public class Child1 : I
interface IGrandparent
{
void DoSomething();
}
interface IParent : IGrandparent
{
void DoSomethingElse();
}
然后有两种实现:
//only includes last interface from the inheritance chain
public class Child1 : IParent
{
public void DoSomething()
{
throw new NotImplementedException();
}
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
// includes all the interfaces from the inheritance chain
public class Child2 : IGrandparent, IParent
{
public void DoSomething()
{
throw new NotImplementedException();
}
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
这两种实现相同吗?(除了类名)?有人说这与“隐式和显式实现”有关,有人能解释为什么吗?我见过的Child2样式比另一种样式更多。隐式接口实现发生在不同接口没有冲突的方法名称时,这是常见的情况。
另一方面,Excplicit是当存在冲突的方法名称时,此时必须指定在方法中实现的接口
public interface IFoo
{
void Do(); // conflicting name 1
}
public interface IBar
{
void Do(); // conflicting name 2
}
public class FooBar : IFoo, IBar
{
void IFoo.Do() // explicit implementation 1
{
}
void IBar.Do() // explicit implementation 1
{
}
}
请注意,免责实现的接口方法不能是公共的。
谈谈你的具体例子。您只能安全地使用iPart
。即使您希望使用excplicit接口实现,也可以在类声明中不特别提到IGrandparent
interface IGrandparent
{
void DoSomething();
}
interface IParent : IGrandparent
{
void DoSomethingElse();
void DoSomething();
}
public class Child : IParent
{
void IGrandparent.DoSomething()
{
}
public void DoSomethingElse()
{
}
public void DoSomething()
{
}
}
EDIT:如前所述,还有其他几种显式接口实现用法,包括接口重新实现。我在中找到了隐式与显式接口实现用法的很好的理由(您可能还想查看整个线程,这很有趣)。它们是相同的
这与显式接口实现无关,因为可以使用Child1
和Child2
样式显式实现接口,例如:
public class Child2 : IGrandparent, IParent
{
void IGrandparent.DoSomething()
{
throw new NotImplementedException();
}
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
public class Child1 : IParent
{
void IGrandparent.DoSomething()
{
throw new NotImplementedException();
}
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
请注意,这不应与类层次结构中的接口重新实现混淆:
public class Child1 : IParent
{
public void DoSomething()
{
Console.WriteLine("Child1.DoSomething");
}
public void DoSomethingElse()
{
Console.WriteLine("Child1.DoSomethingElse");
}
}
public class Child2 : Child1, IGrandparent
{
// Child2 re-implements IGrandparent
// using explicit interface implementation
void IGrandparent.DoSomething()
{
Console.WriteLine("Child2.DoSomething");
}
}
我会避免孩子2的风格。这只是一个视觉垃圾。此外,如果您不负责IGrandparent
,那么有时您会得到:
interface IGrandparent : ICthulhu { ... }
是否要按以下方式更新代码:
public class Child2 : ICthulhu, IGrandparent, IParent { ... }
?“相同”的定义不明确。呃,这是定义明确的,但事实并非如此。但就所有实际目的而言,如果
接口IB:IA
,那么与仅类B:IB
相比,说明类B:IB,IA
是没有意义的。唯一的区别是,如果后来有人更改了IB
而不是从IA
继承。那么这将产生不同。但在设计时通常不需要担心。只需实现IParent,并完成它。如果您更经常看到Child2样式,那么一定要在内部询问原因。我看不出这有什么好处,但也许有人可以澄清一下。如果澄清没有意义,请在这里再次询问。但MS没有明确声明,例如:IEnumerable这是一种风格选择,只有在团队的编码标准规定的情况下,您才“应该”。隐式和显式实现与此无关,如果接口有共同的成员名称,则这两种样式都要求显式。如果你的工作完全没有编码标准,只是没有偏好,那么就按照微软程序员的方式来做,第二种风格。我个人更喜欢第一种风格,但后来我看到第二种风格的列表,这让我怀疑我是否做了错事。“Excplicit…是指方法名称冲突”-实际上,这不是唯一的情况。至少还有两种情况:1)当基类将接口方法映射到非虚拟方法时,接口重新实现;2) 当人们想隐藏特定的接口实现以仅在某些特殊场景下使用它时(例如,请参见EF6中的IObjectContextAdapter
),我更喜欢Child1样式,但太多的Child2样式会让我担心,这就是为什么我有这个问题。谢谢各位。