В последнее время я был очень заинтригован шаблонами проектирования и особенно следовал правильным шаблонам проектирования в моих классах, которые реализуют один или несколько интерфейсов.
Давайте рассмотрим пример.Когда класс реализует IDisposable
, вы должны следовать определенному шаблону, чтобы убедиться, что ваши ресурсы очищены должным образом, путем создания частного метода Dispose (bool dispose), который различает, вызывается ли он финализатором или вызывается изметод публичной утилизации.Кроме того, в этом случае должен быть реализован финализатор, и вам также может понадобиться закрытая переменная bool isDisposed, которая устанавливается методом Dispose, так что любой метод, вызываемый после того, как объект th будет расположен, будет вызывать исключение, поясняющее, что этот объектуже удален, вместо кода внутри метода, вызывающего сбой, потому что некоторые необходимые ресурсы расположены и, следовательно, больше не доступны.
Существует также множество других интерфейсов, которые я обычно реализую, но это не всеЯ уверен, что способ их реализации - предпочтительный способ сделать это, и позже я могу выяснить, что это вызывает незначительную ошибку, которую трудно найти, которая, вероятно, не существовала бы, если бы я следовалправильный шаблон в первую очередь.
Некоторые примеры интерфейсов, которые я хотел бы знать, лучший способ реализации: ISerializable, IComparable, IComparable <>, ICloneable, IEnumerable <> и так далее.Здесь интересны все интерфейсы из Framework, поэтому он не должен ограничиваться теми, что я перечислил выше.
Мне нужны разные интерфейсы, предпочтительный способ и, надеюсь, также ссылка на ресурс наИнтернет, который объясняет, как и почему следует следовать определенному шаблону.
Я надеюсь получить хорошую коллекцию этих шаблонов, так как я знаю, что они могут значительно улучшить мой код, сделать его более правильным и следовать наилучшим образом.-practices
Было бы здорово, если бы для одного и того же интерфейса было несколько шаблонов, чтобы мы могли обсудить, какой из них предпочтительнее.Это также может привести к тому, что некоторые из вас перейдут к новому шаблону или внесут изменения в существующие шаблоны, чтобы еще больше улучшить свой код, и это было бы здорово!
Редактировать
После прочтения комментария Грзениоса я также призываю всех дать контекст, к которому должен применяться шаблон.Например, шаблон IDIsposable следует использовать только в том случае, если у вас есть неуправляемые ресурсы внутри класса, которые вам нужно утилизировать, а не если все объекты, которые вам нужны для утилизации, сами реализуют IDisposable.
Edit 2
Я, наверное, должен сам начать, так как я поставил вопрос здесь.Поэтому я опишу один шаблон, который я хорошо знаю, и это шаблон IDisposable.
Этот шаблон следует использовать только в том случае, если ваш класс содержит один или несколько неуправляемых ресурсов внутри вашего класса, и вы должны убедиться, чтоони избавляются.в этом случае в дополнение к методу Dispose нам понадобится финализатор на тот случай, если пользователь вашего класса забудет его утилизировать.
Итак, первым делом.Ваш класс должен реализовывать интерфейс IDisposable, и вам нужно будет определить публичный метод Dispose как goverend для интерфейса.Этот метод должен выглядеть следующим образом:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
Это вызовет защищенный метод Dispose (bool), который заботится о фактической очистке.
Кроме того, включите в свой класс переменную, чтобы указатьесли класс удален или нет:
private bool alreadyDisposed = false;
GC.SuppressFinalize сообщает сборщику мусора, что этот элемент не нужно завершать, даже если он имеет финализатор.
Тогда вам нужензащищенный метод утилизации.Сделайте его защищенным, а не закрытым, если какой-либо производный класс должен его переопределить:
protected virtual void Dispose(bool isDisposing)
{
if (alreadyDisposed)
{
return;
}
if (isDisposing)
{
// free all managed resources here
}
// free all unmanaged resources here.
alreadyDisposed = true;
}
Финализатор также должен вызвать Dispose (bool), если пользователь забывает очистить:
~SomeClass(){
Dispose(false);
}
Если для работы какого-либо метода требуется удаленный ресурс, сделайте функцию такой:
public void SomeMethod()
{
if (alreadyDisposed)
throw new ObjectDisposedException("SomeClass",
"Called SomeMethod on Disposed object");
// Method body goes here
}
Вот и все. Это обеспечит очистку ресурсов. Предпочтительнее для пользователя вашего класса, вызывающего Dispose, но с добавлением Finalizer в качестве резервного метода.