[英]Explicit interface implementation limitation
我有一个非常简单的场景:“ 人 ”可以是公司的“ 客户 ”或“ 员工 ”。
一个“ 人 ”,可以通过电话与“ 呼叫 ”的方法被调用。
根据“ 人 ”在通话环境中扮演的角色,例如新产品的公告或组织变更的公告,我们应该使用为“ 客户 ”角色提供的电话号码或提供的电话号码为“ 员工 ”角色。
以下是对情况的总结:
interface IPerson
{
void Call();
}
interface ICustomer : IPerson
{
}
interface IEmployee : IPerson
{
}
class Both : ICustomer, IEmployee
{
void ICustomer.Call()
{
// Call to external phone number
}
void IEmployee.Call()
{
// Call to internal phone number
}
}
但是这段代码不能编译并产生错误:
error CS0539: 'ICustomer.Call' in explicit interface declaration is not a member of interface
error CS0539: 'IEmployee.Call' in explicit interface declaration is not a member of interface
error CS0535: 'Both' does not implement interface member 'IPerson.Call()'
这种情况是否有机会以不同的方式在C#中实现,还是我必须找到另一种设计?
如果是这样,你建议用什么替代品?
在此先感谢您的帮助。
你的目标没有意义。
ICustomer
和IEmployee
都没有定义Call()
方法; 他们只是从同一个接口继承该方法。 您的Both
类两次实现相同的接口。
任何可能的Call
呼叫将始终呼叫IPerson.Call
; 没有专门调用ICustomer.Call
或IEmployee.Call
IL指令。
您可以通过在两个子接口中显式重新定义Call
来解决此问题,但我强烈建议您只是给它们不同的名称。
我自己也碰到了这个。
您可以使用组合来解决问题:
interface IPerson
{
void Call();
}
interface ICustomer : IPerson
{
}
interface IEmployee : IPerson
{
}
class Both
{
public ICustomer Customer { get; }
public IEmployee Employee { get; }
}
以上假设Both类中的Employee是IEmployee的自定义实现,并且是基于Both对象构造的。
但这取决于你打算如何使用Both类。
如果你想像这样使用Both类:
((IEmployee)both).Call();
然后你可以使用这个:
both.Employee.Call();
我对我的解决方案的输入感兴趣...
当我希望控制器访问我的类中的一些属性或方法时,我使用了很多组合的显式实现,这些属性或方法应该隐藏在类的常规用法中...
因此,为了能够多次实现IPerson,在本例中,我将使用泛型,以便能够将IPerson接口从客户拆分为员工
interface IPerson<T>
{
void Call();
}
interface ICustomer : IPerson<ICustomer>
{
}
interface IEmployee : IPerson<IEmployee>
{
}
class Both : ICustomer, IEmployee
{
void IPerson<ICustomer>.Call()
{
// Call to external phone number
}
void IPerson<IEmployee>.Call()
{
// Call to internal phone number
}
}
除了SLaks准确指出的问题......
摆脱IPerson
并使用Contact()
方法创建IContactable
,然后创建两个实现IContactable
称为Customer
和Employee
具体类型。 然后,当你需要联系某人时,你可以根据需要调用你的IContactable.Contact()
方法,因为能够进行联系可以扩展,而IPerson
有点抽象。
你不能这样做,因为Call方法来自两种情况下的IPerson接口。 因此,您尝试两次定义Call方法。 我建议您将ICustomer和IEmployee接口更改为类,并在此类中定义Call方法:
interface IPerson
{
void Call();
}
class Customer : IPerson
{
public void Call()
{
}
}
class Employee : IPerson
{
public void Call()
{
}
}
我不知道这是否有帮助,但你可以试一试。
//ran in linqpad c# program mode, you'll need to provide an entry point.....
void Main()
{
IPerson x;
x = new Both(new Employee());
x.call(); //outputs "Emplyee"
x = new Both(new Customer());
x.call(); //outputs "Customer"
}
class Customer : ICustomer
{
public void call() {"Customer".Dump();}
}
class Employee : IEmployee
{
public void call() {"Employee".Dump();}
}
class Both : IPerson
{
private IPerson Person { get; set; }
public Both(IPerson person)
{
this.Person = person;
}
public void call()
{
Person.call();
}
}
interface IPerson { void call(); }
interface ICustomer : IPerson { }
interface IEmployee : IPerson { }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.