Другое возможное решение (принимающий Вас на самом деле нуждаются в надежных адресных сведениях и Вы только используете адреса в качестве способа предотвратить дублирующиеся учетные записи), должен использовать сторонний веб-сервис для стандартизации адресов, обеспеченных пользователями.
Это прокладывает себе путь - Ваша система принимает адрес пользователя через форму онлайн. Ваша форма руки прочь от адреса пользователя к стороннему веб-сервису стандартизации адреса. Веб-сервис дает Вам назад тот же адрес, но теперь с данными, стандартизированными в дискретные поля адреса, и со стандартными сокращениями, и форматирует примененный. Ваши отображения приложения этот стандартизированный адрес Вашему пользователю для их подтверждения прежде, чем попытаться сохранить данные в Вашем DB.
, Если все пользовательские адреса проходят шаг стандартизации и только стандартизированные адреса сохраняются к Вашему DB, то нахождение дублирующихся записей должно быть значительно упрощено, так как Вы теперь сравниваете яблоки с яблоками.
Один такой сторонний сервис Интерактивный Сервис Глобального Адреса , который включает Германию в список поддерживаемых стран, и также имеет демонстрацию онлайн, которая демонстрирует, как их сервис работает (демонстрационная ссылка может быть найдена на той веб-странице).
существует невыгодное соотношение издержек к этому подходу, очевидно. Однако зато:
Правовая оговорка: Я не работаю на Глобальный Адрес и не попытался использовать их сервис. Я просто упоминаю их как пример, так как у них есть демонстрация онлайн, с которой можно на самом деле играть.
«Разве инициализация объекта вне конструктора не нарушает инкапсуляцию?»
Ну, нет. Как вы правильно заметили, вы можете инициализировать только те свойства, которые уже доступны в вашей текущей области. (общедоступная, внутренняя и т. д.)
Этот вид инициализации на самом деле представляет собой лишь некоторый синтаксический сахар вокруг создания класса и присвоения значений свойствам. Он очень полезен для анонимных классов и предложений Linq select.
Обычно считается плохой практикой раскрывать общедоступные поля ... в некоторых случаях это может быть приемлемо, например, если поле отмечено как только для чтения
(что означает должен быть установлен в конструкторе). Вместо этого вы должны сделать это поле закрытым и раскрыть его через свойство, которое может быть или не доступно только для чтения, в зависимости от его назначения:
class MyClass
{
private string _aString;
public string AString
{
get { return _aString; }
// uncomment to make the property writable
//set { _aString = value; }
}
}
Если рассматривать свойства как геттеры и сеттеры, я не верю, что это нарушит инкапсуляцию. Но вы должны заметить, что вы не использовали свойство, вы использовали переменную экземпляра. На самом деле, я не верю, что это сработает, как ваш пример. Отметьте этот:
class MyClass {
private string aString;
public string AString {
get { return aString; }
set {aString = value; }
}
}
MyClass test = new MyClass {
AString = "test"
};
В этом случае, вы получаете доступ к частному полю через его аксессор. Это похоже на использование конструктора без параметров и установку значения позже.
Если вы спрашиваете, нарушает ли сокращенная запись инициализации нового объекта инкапсуляцию, то ответ отрицательный. С помощью нового метода можно установить только члены с общедоступной областью действия.
MyClass test = new MyClass { _aString = "Test" };
то же самое, что
MyClass test = new MyClass();
test._aString = "Test";
Отображение общедоступного объекта в классе C # не нарушает "инкапсуляцию" с точки с точки зрения «объектно-ориентированного программирования».
С точки зрения «хорошей практики» это нехорошо, используйте свойства, потому что это позволяет внешнему коду использовать этот класс, если вы измените поведение обновления этого значение (проверка, ...).
Это зависит от назначения переменной. Если программист должен иметь возможность устанавливать переменную только при инициализации, но затем не иметь к ней доступа после этого, я бы выбрал частную переменную. Если вы хотите, чтобы пользователь класса мог устанавливать / читать переменную в любое время, сделайте ее общедоступной.
да, инициализировать через конструктор и добавлять свойства, чтобы разрешить (или запретить) доступ к данным.
class MyClass {
private string _aString;
string MyProperty {
get { return this._aString; }
// you can make this private or protected
set { this._aString = value; }
}
}
Когда у вас есть
публичная строка _aString;
действительно не имеет значения, когда вы инициализируете это значение, поскольку оно уже выставлено. Итак, когда мы хотим поговорить об инициализации, мы должны переместить эту строку в свойство. Разговор об инкапсуляции имеет смысл.
Итак, представьте, что у нас есть строка. Есть два подхода к инициализации. Один - сделать это внутри конструктора, второй - это ленивая инициализация (инициализация, когда некоторые запрашивают эти данные).