Существует одна типичная проблема с проверкой аргументов в конструкторах классов-наследников, которые должны передавать «куски» своих аргументов базовому классу. Простой пример этой проблемы выглядит так:
abstract class Base
{
private readonly int _length;
protected Base(int length)
{
if (length <= 0) throw new ArgumentOutOfRangeException("length");
_length = length;
}
}
internal class Derived : Base
{
public Derived(string s)
: base(s.Length)
{
// Проверка бесполезна!
if (string.IsNullOrEmpty(s)) throw new ArgumentNullException("s");
}
}
Проблема в том, что конструктор базового класса вызывается до тела метода конструктора Derived (*). В результате, если конструктор наследника принимает составной объект и «выкусывает» часть, которая нужна конструктору базовому классу, то нормально проверить валидность составного объекта не получиться.