2014-01-24 6 views
2

У меня есть класс node, который в основном состоит из свойства parent и списка ребенок. Существует метод AddChild, который не должен принимать значение null в качестве аргумента. Пользователи не должны добавлять нулевой дочерний элемент.Создайте метод или список, который не может принимать пустые аргументы

Но свойство parent должно допускать нулевые значения (корневой узел имеет нулевой родительский элемент).

Вопрос: «Как запретить пользователям добавлять пустых детей в compile-time?». Я знаю, что могу добавить NullArgumentException, но это не то, что мне нужно.

Другой способ создания списка, который не принимает нулевые элементы (время компиляции).

Код:

class Node 
{ 
    public Node Parent { get; set; } 
    private List<Node> Children = new List<Node>(); 

    public void AddChild<Maybe a generics solution?>(Node???? Child) where ???? 
    { 
     //I don't want to add (if Child == null) Throw new ArgumentNullException(); 
     Children.Add(Child); 
    } 
} 
+1

C# не поддерживает эту функцию. – SLaks

+0

Какова причина того, что вы не хотите иметь if-условие внутри вашего метода AddChild, проверяя, прошел ли нулевой параметр? –

+0

Близко связано с: http://stackoverflow.com/questions/6365459/create-non-nullable-type-in-c-sharp –

ответ

3

Это "недостаток" дизайна C# языка. Существует способ сделать тип значения (struct T) нулевым (Nullable<T>), но нет способа указать аргумент ссылочного типа, который не должен быть нулевым. Лучшее, что вы можете сделать, это проверить значение null и бросить ArgumentNullException (или использовать кодовые контракты, как предлагает pnewhook).

См. Ответ MailmanOdd на ссылку в блоге Эрика Липперта по этой теме.

+0

Это хорошая идея, попытка инвертировать вещи и сделать узел структурой, а 'parent' будет' Nullable '... Я буду думать о последствиях ... –

+0

@ Daniel Это не сработает, к сожалению , Структура - это тип значения, поэтому вы * не можете * указать один узел на другой. Вы на правильном пути, используя класс, но вам придется жить с ручной нулевой проверкой. –

2

Вы не можете отменить нулевые аргументы, лучше всего это сделать ошибку, если нарушено предварительное условие аргумента. Поскольку вы не хотите бросать ArgumentNullException, если ребенок имеет значение null, я бы рекомендовал code contracts.

Contract.Requires(x != null); 

Это немного более лаконично, и вы получите дополнительную возможность статический проверок во время сборки, если ваше предварительное условие нарушаются.

+0

Извините ... Я не понимаю, что вы подразумеваете под «статической проверкой времени сборки» ... –

+0

С небольшим количеством инструментов для Visual Studio вы можете запустить проверку как часть своей сборки, чтобы узнать, код вызывает метод таким образом, который нарушает договор. Это «статический», поскольку код фактически не выполняется, просто оценивается. – pnewhook