2017-06-11 16 views
2

私は、共通のベースから派生したクラスのインターフェースを実装するクラスを持っています。私はこれらを組み合わせて、セットとしてそれらと一緒に働くことができる方法はありますか?派生クラスのインターフェースを組み合わせる

私は共変反を探求していますが、成功しません。

ありがとうございました。

void Main() 
{ 
    var textAnswers = new IAnswerValidator<TextQuestion, TextAnswer>[] { new NoDogsValidator(), new MaxLengthValidator() }; 
    var dateAnswers = new IAnswerValidator<DateQuestion, DateAnswer>[] { new NotChristmasDayValidator() }; 

    // Can I combine into a list or enumerable? 
    // var allValidators = new List<IAnswerValidator<QuestionBase, AnswerBase>>(); 
    // allValidators.AddRange(textAnswers); 
    // allValidators.AddRange(dateAnswers); 


    // The goal is to be able to combine so as to be able to work on them as a set. 
} 

public class ValidationResult { } 

public class AnswerBase { } 
public class TextAnswer : AnswerBase { } 
public class DateAnswer : AnswerBase { } 

public class QuestionBase { } 
public class TextQuestion : QuestionBase { } 
public class DateQuestion : QuestionBase { } 

public interface IAnswerValidator<TQuestion, TAnswer> where TQuestion : QuestionBase, new() where TAnswer : AnswerBase, new() 
{ 
    ValidationResult Validate(TQuestion question, TAnswer answer); 
} 

public class NoDogsValidator : IAnswerValidator<TextQuestion, TextAnswer> 
{ 
    public ValidationResult Validate(TextQuestion question, TextAnswer answer) { return new ValidationResult(); } // simplified 
} 

public class MaxLengthValidator : IAnswerValidator<TextQuestion, TextAnswer> 
{ 
    public ValidationResult Validate(TextQuestion question, TextAnswer answer) { return new ValidationResult(); } // simplified 
} 

public class NotChristmasDayValidator : IAnswerValidator<DateQuestion, DateAnswer> 
{ 
    public ValidationResult Validate(DateQuestion question, DateAnswer answer) { return new ValidationResult(); } // simplified 
} 

答えて

3

私はセットとして一緒に仕事するには、これらを組み合わせることができます方法はありますか?

型の安全性を保ちません。たとえば、あなたの提案コードを検討

var allValidators = new List<IAnswerValidator<QuestionBase, AnswerBase>>(); 
allValidators.AddRange(textAnswers); 
allValidators.AddRange(dateAnswers); 

は、コンパイラは、あなたがそれをやらせるとします。特に

QuestionBase question = new TextQuestion(); 
AnswerBase answer = new TextAnswer(); 

foreach (var validator in allValidators) 
{ 
    validator.Validate(question, answer); 
} 

それは、リスト内のNotChristmasDayValidator要素になったとき、どのようなそのオブジェクトはあなたがそのValidate()メソッドオブジェクトを渡すときに実行するために起こっている:そして、あなたはこのような何かを行う場合にどうするかを言うのですかそれぞれDateQuestionDateAnswerではありませんか?

あなたの目標は根本的に壊れています。あなたは、すべてのオブジェクトを1つのリストにまとめたいと思っていますが、それがなぜ役に立つのか、そのようなリストを使って何ができると思うのか説明していません。もちろん、タイプセーフティを破棄するだけで、これらのオブジェクトをすべて同じリストに入れることができます。たとえば、代わりにallValidatorsオブジェクトをList<object>にします。次に、あなたが望むものをリストに入れることができます。しかし、リストを使用するときは、後で余分なタイプチェックを行う必要があります。

あなたが安全で賢明な設計目標を説明することができるときは、「いいえ、できません。安全ではありません。

+0

ありがとうございました。よく説明されています。 –

関連する問題