2011-09-15 55 views
3

私は次のインターフェイスとクラスのセットを持っています。複数のインターフェイス実装との混乱

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に問題がIDeviceDataObjectがIValidatableObjectインターフェイスを実装していないため、コンパイラは()device.Validateを解決できないということです。

私の質問はIValidatableObjectIValidatableObjectに変更することです。私はそれが良いかどうかについては少し不確実ですが、私はそれが見える方法がDeviceDataObjectIValidatableObjectを2回実行しています.1回はValidatableObjectで、もう一度はIDeviceDataObjectです。誰も私のためにこれをクリアするのに役立つことができますか?

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

なぜあなたのValidateDeviceの署名は '' public bool ValidateDevice(IValidatableObject someobj) ''のように見えませんか?検証メソッドの機能を表現するものはありません:検証可能なものが必要です。それ以外のものはそれがそのまま残ることができます。 –

+0

フェアコール。しかし、それが渡されるIDeviceDataObjectであることを知る必要があったが、それでもIValidatableObject機能を持つ必要があったCreateDeviceメソッドの場合はどうでしょうか? – Chris

+0

だから私はここでもっと大きな画像を知らないので、すべてのIDeviceDataObjectsを有効にする必要がありますか? yesの場合、 '' IDeviceDataObject''は '' IValidatableObject''から継承します。そうでない場合、これは解決策ではありません。それは時には本当に単純なことです。意味論的に意味をなさないことの単なる問題です。これをコードに変換することは、やや簡単なステップです。 –

答えて

1

私はここで何か間違ったことを理解しているかもしれませんが、あなたのクラスアーキテクチャ全体を知っているわけではありませんが、ValidateDeviceメソッドが有効なオブジェクトを取るのはなぜですか?

public bool ValidateDevice(IValidatableObject someobj) 

何が検証ないメソッドの機能発現することがありえない:それはvalidatableで何かを取るの署名は次のようになります。あなたは必ずValidateDeviceのみということにしたい場合は他のすべてが、それは方法(つまり、あなたがいないすべてのdevicedataobjectはまた、例えばvalidatableであることを表現したいこととして、IValidatableObjectからIDeviceDataObject継承を聞かせてはいけない)

第二の方法とどまることができます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 
} 
0

あなたは、インターフェイスの右の組み合わせを実装するオブジェクトインスタンスに渡すために、呼び出し元にそれを残して、あなたのValidateDevice方法は、一般的な作ることができる - これはあなたのインタフェースは独立したままで、まだ型の安全性を強化することが可能になります。

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

をあなたは単にIValidatableObjectにキャストできます。

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

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

有効な状態ではあるが 'IValidatableObject'を実装していないすべてのデバイスは、検証に失敗します。 – Eranga

+0

@エランガ - そして?彼らが有効であることを通知できる唯一の方法は、IValidatableObjectを実装することです。私は問題を見ない。 –

+0

APIが横たわっています。私は 'ValidateDevice'メソッドが' IDeviceDataObject'契約に基づいてバリデーションを行うことを期待しています。私は 'ValidateDevice'の実装を通して、' IValidatableObject'も実装しなければならないことを知っておく必要があります。 – Eranga

0

私は名前から多くのことを推測するんだけど、IDeviceDataObjectIValidatableObjectは別のアイデアであるかのように、それは私には見えます。 IDeviceDataObjectIValidatableObject、またはその両方(yes?)のいずれかを実装するオブジェクトを持つことは妥当と思われます。これが当てはまる場合、2つのインターフェイス間に「is a」の関係はありません(IDeviceDataObjectIValidatableObjectと仮定しません)。したがって、一方のインターフェイスを継承することは間違っています。

ValidateDeviceメソッド(または任意の方法) - 引数をIDeviceDataObjectとして使用する場合、引数はその型にする必要があります。引き数をIValidatableObjectとして使用する場合は、引数は、つまりとなるはずです。両方の機能を使用する場合は、あまり具体的でない型を渡して、そのオブジェクトが特定のインタフェースをサポートしているかどうかを確認するためにC# 'is'または 'as'を使用してランタイムチェックを行いたい場合があります。

関連する問題