简体   繁体   English

与多个接口实现混淆

[英]Confusion with multiple interface implementation

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. 上面的服务操作ValidateDevice中的问题是编译器无法解析device.Validate(),因为IDeviceDataObject没有实现IValidatableObject接口。

My question is, is it then correct to change IValidatableObject to implement IValidatableObject . 我的问题是,更改IValidatableObject以实现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 . 我有点不确定这是否是一种好的做法,因为我看到它的方式, DeviceDataObject实现IValidatableObject两次 - 一次通过ValidatableObject ,一次通过IDeviceDataObject Can anyone help clear this up for me? 任何人都可以帮我解决这个问题吗?

public interface IDeviceDataObject : IValidatableObject
{
   int Id { get; set; }
   string Name { get; set; }
}

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? 我可能在这里理解错误(我不知道你的类架构作为一个整体),但为什么你的ValidateDevice方法不能只接受有效的对象? The signature would look like: 签名看起来像:

public bool ValidateDevice(IValidatableObject someobj)

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 (ie dont let IDeviceDataObject inherit from IValidatableObject , as you may want to express that not every devicedataobject is also validatable for example) 其他所有东西都可以保持IDeviceDataObject (即不要让IDeviceDataObject继承自IValidatableObject ,因为你可能想要表明并非每个devicedataobject都可以被验证)

A second way, if you want to make sure that ValidateDevice only takes objects implementing IDeviceDataObject , you could also try to cross-cast to IValidatableObject : 第二种方法,如果你想确保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
}

You could simply cast to IValidatableObject. 您可以简单地转换为IValidatableObject。

public class DeviceService 
{ 
   public bool ValidateDevice(IDeviceDataObject device) 
   { 
       IValidatableObject v = device as IValidatableObject;

       if (v != null)
           return device.Validate();
       return false;
   } 
} 

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: 您可以使您的ValidateDevice方法通用,将其留给调用者传入实现正确接口组合的对象实例 - 这将允许您的接口保持独立并仍然强制类型安全:

public class DeviceService
{
   public bool ValidateDevice<T>(T device) where T: IDeviceDataObject, IValidatableObject
   {
       return device.Validate(); 
   }
}

I'm inferring a lot from the names, but it looks to me as if IDeviceDataObject and IValidatableObject are separate ideas. 我从名称中推断出很多,但它看起来好像IDeviceDataObjectIValidatableObject是不同的想法。 It seems reasonable that you could have objects which implement either IDeviceDataObject , IValidatableObject , or both (yes?). 你可以拥有实现IDeviceDataObjectIValidatableObject或两者的对象似乎是合理的(是吗?)。 If this is true, then there is no "is a" relationship between the two interfaces (you wouldn't assume IDeviceDataObject is a IValidatableObject ), so inheriting one interface from the other seems wrong. 如果这是真的,那么两个接口之间就没有“是一个”关系(你不会认为IDeviceDataObject是一个IValidatableObject ),所以从另一个继承一个接口似乎是错误的。

As for your ValidateDevice method (or any method) -- if it's going to use the argument as a IDeviceDataObject , the argument should be of that type. 对于您的ValidateDevice方法(或任何方法) - 如果它将使用该参数作为IDeviceDataObject ,则该参数应该是该类型。 If it's going to use the argument as an IValidatableObject , the argument should be of that type. 如果它将使用参数作为IValidatableObject ,则参数应该是类型。 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. 如果它可能使用这两种功能,您可能希望传入一个不太具体的类型,然后进行运行时检查(使用C#'is'或'as')来查看该对象是否支持特定接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM