2009-10-14 2 views
1

Допустим, у меня есть номер телефона, который мои классы должны проверять и отслеживать, и по большей части телефонный номер - это просто строка, поэтому, пытаясь быть СУХОЙ, можно просто создать класс телефона и наследовать от строки. Так как я не могу сделать то, что является следующим лучшим подходом? Добавление строки в качестве частного члена и перегрузка равных/= операторов, чтобы она могла быть передана и задана как строка?Inheriting From Sealed Classes

ответ

1

Могу ли я предложить вам взять рекомендации Йоханнеса Рудольфа или К. Росса. Вы также можете просмотреть поведение ключевого слова implicit, которое позволит вам назначать String-подобным образом при выполнении проверки.

т.е .:

public class PhoneNumber { 

    private String number; 

    public PhoneNumber(String s) { 
     // validation code here, throw exception if not valid 
     number = s; 
    } 

    public static implicit operator PhoneNumber(String s) { 
     return new PhoneNumber(s); 
    } 
} 
7

предпочитает композицию над наследованием.

Вы хотите, чтобы ваш номер телефона был назначен из строки? Конечно, не потому, что следующий будет возможным, то:

Person.PhoneNumber = "FOO" 

Нечто подобное чувствует себя более естественно:

Person.PhoneNumber = new PhoneNumber("015-123456"); 

Вы можете сделать пользовательскую проверку в конструкторе и дополнительно решите, что вы хотите быть неизменны (ок , строка тоже была бы неизменной)

+0

Я понимаю, что, принимая Person.PhoneNumber = "Foo" и бросает исключение является лучшей практикой, то Person.PhoneNumber = новый PhoneNumber ("Foo"); бросая исключение для конструктора. Но это могут быть только мои звонки на фоне C++. –

+0

Ваши звонкие колокола, как правило, правильные, но мы работаем в среде GC здесь, поэтому безуспешное создание объекта не представляет проблемы. Вы также можете сделать конструктор Person.PhoneNumber закрытым и предоставить статический метод PhoneNumber.Parse, который отвечает за создание экземпляра PhoneNumber и проверку строки. –

1

Я бы создал класс PhoneNumber с частным членом строки, как вы предложили. Вы можете переопределить метод ToString(), если хотите обеспечить согласованное форматирование (например, (123) 123-1234 или что-то еще), вы можете добавить некоторую проверку на метод набора или конструктор, чтобы убедиться, что номер телефона имеет 10 цифр (если североамериканский номер).

Создание класса PhoneNumber позволяет вам расширить класс позже, если вам нужно. Например, вы можете улучшить проверку номера телефона, чтобы проверить наличие недопустимых кодов областей и вызвать ошибку, если код области не существует.

2

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

PhoneNumber p = PhoneNumber.Parse("704 - 576- 4000"); 

Это более стандартный и читаемый. Кроме того, даже если вы могли бы наследовать строку, я бы посоветовал это сделать, поскольку String имеет сложную внутреннюю функциональность, которая должна быть отделена от вашего класса. Кроме того, наследование из строки будет вызывать ряд методов, которые не имеют смысла для номера телефона (то есть: Concat, неточно сравниваются и т. Д.).