与多个接口实现混淆

时间:2011-09-15 01:11:34

标签: c# oop inheritance interface refactoring

我有以下一组接口和类。

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; }
}

4 个答案:

答案 0 :(得分:1)

我可能在这里理解错误(我不知道你的类体系结构整体),但为什么你的ValidateDevice方法不能只接受有效的对象?签名看起来像:

public bool ValidateDevice(IValidatableObject someobj)

不表示执行验证的方法的功能:它需要 validatable 。其他所有东西都可以保持原样(即不要让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
}

答案 1 :(得分:1)

您可以简单地转换为IValidatableObject。

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

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

答案 2 :(得分:0)

你可以使你的ValidateDevice方法通用,让它留给调用者传入实现正确接口组合的对象实例 - 这将允许你的接口保持独立并仍然强制类型安全:

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

答案 3 :(得分:0)

我从名字中推断出很多,但它看起来好像IDeviceDataObjectIValidatableObject是不同的想法。你可以拥有实现IDeviceDataObjectIValidatableObject或两者的对象(是吗?)似乎是合理的。如果这是真的,那么两个接口之间就没有“是一个”关系(你不会认为IDeviceDataObjectIValidatableObject),所以从另一个继承一个接口似乎是错误的。

至于你的ValidateDevice方法(或任何方法) - 如果它将参数用作IDeviceDataObject,则参数应该是该类型。如果它将使用参数作为IValidatableObject,则参数应为 类型。如果它可能使用这两种功能,您可能希望传入一个不太具体的类型,然后进行运行时检查(使用C#'is'或'as')来查看该对象是否支持特定接口。