多个接口实现的混乱
我有以下一组接口和类。
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
code> 并通过 IDeviceDataObject
一次。谁能帮我解决这个问题吗?
public interface IDeviceDataObject : IValidatableObject
{
int Id { get; set; }
string Name { get; set; }
}
I have the following set of Interfaces and Classes.
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
}
}
The problem in the service operation ValidateDevice above is that the compiler can't resolve device.Validate() because IDeviceDataObject does not implement the IValidatableObject interface.
My question is, is it then correct to change IValidatableObject
to implement IValidatableObject
. I'm a little uncertain as to whether this is good practice because the way I kind of see it, DeviceDataObject
is implementing IValidatableObject
twice - once through ValidatableObject
and once through IDeviceDataObject
. Can anyone help clear this up for me?
public interface IDeviceDataObject : IValidatableObject
{
int Id { get; set; }
string Name { get; set; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我可能在这里理解错误(并且我不知道您的整个类架构),但是为什么您的 ValidateDevice 方法不只采用可验证的对象?签名看起来像:
这不正是表达了进行验证的方法的功能吗:它需要一些可验证的东西。其他一切都可以保持原样(即不要让
IDeviceDataObject
继承IValidatableObject
,因为您可能想表达并非每个 devicedataobject 也是可验证的)第二种方式,如果您想确保
ValidateDevice
仅接受实现IDeviceDataObject
的对象,您还可以尝试交叉转换为IValidatableObject
:I may understand something wrong here (and I dont know your class architecture as a whole), but why doesn't your ValidateDevice method just take validatable objects? The signature would look like:
Isnt that what expresses the functionality of a method that does validation: it takes something that is validatable. Everything else could stay the way it is (i.e. dont let
IDeviceDataObject
inherit fromIValidatableObject
, as you may want to express that not every devicedataobject is also validatable for example)A second way, if you want to make sure that
ValidateDevice
only takes objects implementingIDeviceDataObject
, you could also try to cross-cast toIValidatableObject
:您可以简单地转换为 IValidatableObject。
You could simply cast to IValidatableObject.
您可以使您的 ValidateDevice 方法变得通用,让调用者自行传递实现正确接口组合的对象实例 - 这将允许您的接口保持独立并仍然强制类型安全:
You could make your
ValidateDevice
method generic to leave it up to the caller to pass in object instances that implement the right combinations of interfaces - this would allow your interfaces to remain independent and still enforce type safety:我从名称中推断了很多,但在我看来,
IDeviceDataObject
和IValidatableObject
是不同的想法。您可以拥有实现IDeviceDataObject
、IValidatableObject
或两者的对象,这似乎是合理的(是吗?)。如果这是真的,那么两个接口之间不存在“是”关系(您不会假设IDeviceDataObject
是IValidatableObject
),因此从其他好像错了。至于您的
ValidateDevice
方法(或任何方法)——如果它将参数用作IDeviceDataObject
,则参数应该是该类型。如果要将参数用作IValidatableObject
,则参数应该是that 类型。如果它可能使用这两种功能,您可能需要传入不太具体的类型,然后执行运行时检查(使用 C#“is”或“as”)以查看对象是否支持特定接口。I'm inferring a lot from the names, but it looks to me as if
IDeviceDataObject
andIValidatableObject
are separate ideas. It seems reasonable that you could have objects which implement eitherIDeviceDataObject
,IValidatableObject
, or both (yes?). If this is true, then there is no "is a" relationship between the two interfaces (you wouldn't assumeIDeviceDataObject
is aIValidatableObject
), so inheriting one interface from the other seems wrong.As for your
ValidateDevice
method (or any method) -- if it's going to use the argument as aIDeviceDataObject
, the argument should be of that type. If it's going to use the argument as anIValidatableObject
, the argument should be of that type. If it might use both pieces of functionality, you might want to pass in a less specific type and then do a runtime check (using C# 'is' or 'as') to see if the object supports the particular interface.