与多个接口实现混淆
本文关键字:实现 接口 | 更新日期: 2023-09-27 18:08:32
我有以下一组接口和类。
public interface IValidatableObject
{
List<string> ValidationErrors { get; }
bool Validate();
}
public class ValidatableObject : IValidatableObject
{
public List<string>ValidationErrors { get; }
public bool Validate()
{
//dostuff
}
}
public interface IDeviceDataObject
{
int Id { get; set; }
string Name { get; set; }
}
public class DeviceDataObject : ValidatableObject, IDeviceDataObject
{
public int Id { get; set; }
public string Name { get; set; }
}
public class DeviceService
{
public bool ValidateDevice(IDeviceDataObject device)
{
return device.Validate(); // This throws a compiler error
}
}
上面的服务操作ValidateDevice中的问题是编译器无法解析device.Validate(),因为IDeviceDataObject没有实现IValidatableObject接口。
我的问题是,改变IValidatableObject
来实现IValidatableObject
是正确的吗?我有点不确定这是否是一个好的实践,因为我看到它的方式,DeviceDataObject
实现了IValidatableObject
两次-一次通过ValidatableObject
,一次通过IDeviceDataObject
。有人能帮我澄清一下吗?
public interface IDeviceDataObject : IValidatableObject
{
int Id { get; set; }
string Name { get; set; }
}
我可能在这里理解了一些错误(我不知道你的类架构作为一个整体),但为什么你的ValidateDevice方法不只是接受可验证的对象?签名看起来像:
public bool ValidateDevice(IValidatableObject someobj)
这不就是表达验证方法的功能吗?它接受可验证的东西。其他一切都可以保持原样(例如,不要让IDeviceDataObject
继承IValidatableObject
,因为您可能想表达并非每个devicedataobject也可验证)
ValidateDevice
只接受实现IDeviceDataObject
的对象,你也可以尝试交叉强制转换到IValidatableObject
:
public bool ValidateDevice(IDeviceDataObject someobj)
{
if(someobj is IValidatableObject)
{
return ((IValidatableObject)device).Validate();
}
return //something that makes sense if the device is not validatable
}
可以直接转换为IValidatableObject
public class DeviceService
{
public bool ValidateDevice(IDeviceDataObject device)
{
IValidatableObject v = device as IValidatableObject;
if (v != null)
return device.Validate();
return false;
}
}
你可以让你的ValidateDevice
方法泛型,把它留给调用者来传递实现接口正确组合的对象实例——这将允许你的接口保持独立,并且仍然强制类型安全:
public class DeviceService
{
public bool ValidateDevice<T>(T device) where T: IDeviceDataObject, IValidatableObject
{
return device.Validate();
}
}
我从名字中推断了很多,但在我看来,IDeviceDataObject
和IValidatableObject
是分开的想法。这似乎是合理的,你可以有对象实现IDeviceDataObject
, IValidatableObject
,或两者(是吗?)。如果这是真的,那么两个接口之间没有"是"关系(您不会假设IDeviceDataObject
是IValidatableObject
),因此从一个接口继承另一个接口似乎是错误的。
对于您的ValidateDevice
方法(或任何方法)—如果它将参数用作IDeviceDataObject
,则参数应该是该类型。如果要将参数用作IValidatableObject
,则参数应该是类型的。如果它可能使用这两种功能,你可能想传入一个不太具体的类型,然后做一个运行时检查(使用c# 'is'或'as'),看看对象是否支持特定的接口。