考虑以下片段。如何正确实现public void GiveFood(IAnimal d)
部分?编译器希望实现两个独立的成员接口(ISeaAnimal和ILandAnimal(,但它们由IAnimal方法处理。
interface IAnimal { }
interface ILandAnimal : IAnimal { }
interface ISeaAnimal : IAnimal { }
interface ICaretaker<in T> where T : IAnimal
{
void GiveFood(T d);
}
interface ISeaAnimalCaretaker<in T> : ICaretaker<T> where T : ISeaAnimal
{
void RefreshWater();
}
class SuperCaretaker : ISeaAnimalCaretaker<ISeaAnimal>, ICaretaker<IAnimal>
{
public void RefreshWater()
{
// ...
}
public void GiveFood(IAnimal d)
{
// ...
}
// ---> The below methods are redundant since GiveFood(IAnimal) is implemented, but the compiler wants them still
//public void GiveFood(ISeaAnimal d)
//{
// throw new NotImplementedException();
//}
//public void GiveFood(ILandAnimal d)
//{
// throw new NotImplementedException();
//}
使用显式接口实现怎么样?注意,SuperCaretaker
同时实现ICaretaker<IAnimal>
和ICaretaker<ISeaAnimal>
:
class SuperCaretaker : ISeaAnimalCaretaker<ISeaAnimal>, ICaretaker<IAnimal>
{
public void RefreshWater()
{
// ...
}
public void GiveFood(IAnimal d)
{
// ...
}
void ICaretaker<ISeaAnimal>.GiveFood(ISeaAnimal d) => GiveFood(d);
}
通过这种方式,ISeaAnimal
方法是隐藏的,除非您使用类型为ICaretaker<ISeaAnimal>
或ISeaAnimalCaretaker<ISeaAnimal>
的表达式访问它。这也意味着您可以在实现中直接调用GiveFood(d);
,而不会导致无限递归。
您不需要GiveFood(ILandAnimal)
方法,因为SuperCaretaker
不实现ICaretaker<ILandAnimal>
,但如果它实现了(我不明白您为什么需要…(,您可以编写另一个显式接口实现。
从SuperCaretaker类中删除ISeaAnimalCareaker实现,这样您就可以处理IAnimal实例。
像这样:
class SuperCaretaker : ICaretaker<IAnimal>
{
public void RefreshWater()
{
// ...
}
public void GiveFood(IAnimal d)
{
// ...
}
// You don't need the other method anymore
}