梳理派生类的接口

时间:2017-06-11 22:39:03

标签: c#

我有一些类来实现从公共库派生的类的接口。有什么方法可以将它们组合起来作为一组使用它们吗?

我一直在探索合作和逆转,但没有成功。

感谢您的帮助。

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
}

1 个答案:

答案 0 :(得分: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()和{{1的DateQuestion方法对象时,该对象将会执行的操作是什么分别是?

你的目标从根本上被打破了。你说你想把所有的对象组合成一个列表,但是你没有解释为什么这个有用,也没有你认为你能用这个列表做什么。当然有一些方法可以将所有这些对象放入同一个列表中,但只能放弃类型安全性。例如,只需将DateAnswer对象设为allValidators即可。然后你可以把你想要的东西放在列表中。但是,在使用列表时,您将不得不进行额外的类型检查。

直到你能够解释一个安全和明智的设计目标,我们现在可以说的是“不,你不能这样做,这不安全”。