C#通用接口-实现专用接口的通用化



考虑以下片段。如何正确实现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
}

最新更新