В моих классах я реализую IDisposable следующим образом:
public class User : IDisposable
{
public int id { get; protected set; }
public string name { get; protected set; }
public string pass { get; protected set; }
public User(int UserID)
{
id = UserID;
}
public User(string Username, string Password)
{
name = Username;
pass = Password;
}
// Other functions go here...
public void Dispose()
{
// Clear all property values that maybe have been set
// when the class was instantiated
id = 0;
name = String.Empty;
pass = String.Empty;
}
}
В VS2012 мой Анализ кода говорит о правильной реализации IDisposable, но я не уверен, что я здесь сделал неправильно.
Точный текст выглядит следующим образом:
CA1063 Внедрение IDisposable правильно Предоставьте переопределяемую реализацию Dispose (bool) для «User» или пометьте тип как закрытый. Вызов Dispose (false) должен только очистить собственные ресурсы. Вызов Dispose (true) должен очистить как управляемые, так и собственные ресурсы. stman User.cs 10
Для справки: CA1063: правильно реализовать ID
Я прочитал эту страницу, но боюсь, я не совсем понимаю, что здесь нужно сделать.
Если кто-то может объяснить более ламенными терминами, в чем заключается проблема и / или как должна реализовываться IDisposable, это действительно поможет!
Dispose
?IDispoable
случае, если у вас есть неуправляемые ресурсы, которыми можно распоряжаться (это включает неуправляемые ресурсы, которые обернуты (SqlConnection
,FileStream
и т. Д.). Вы не реализуете и не должны внедрять,IDisposable
если у вас есть только такие управляемые ресурсы, как здесь. Это, IMO, основная проблема анализа кода. Он очень хорош для проверки маленьких глупых правил, но не хорош для проверки концептуальных ошибокОтветы:
Это было бы правильной реализацией, хотя я не вижу ничего, что вам нужно располагать в коде, который вы разместили. Вам нужно реализовать только
IDisposable
тогда, когда:Ничто в опубликованном вами коде не должно быть уничтожено.
источник
using(){ }
когда это возможно, но для этого вам нужно реализовать IDisposable, поэтому в целом я предпочитаю обращаться к классу через usings, esp. если мне нужен только класс в одной или двух функцияхusing
блок, когда класс реализует IDisposable . Если вам не нужен класс для одноразового использования, не используйте его. Это не имеет смысла.using
блока имеет тенденцию быть привлекательной внеIDisposable
интерфейса. Я предполагаю, что было больше чем несколько злоупотребленийIDisposable
только для целей обзора.GC.SuppressFinalize(this);
бессмысленно. Как отметил @mariozski, финализатор поможет гарантировать, что онDispose
вызывается вообще, если класс не используется внутриusing
блока.Прежде всего, вам не нужно «убирать»
string
s иint
s - они будут автоматически обработаны сборщиком мусора. Единственное, что нужно очистить,Dispose
- это неуправляемые ресурсы или управляемые ресурсы, которые реализуютсяIDisposable
.Однако, предполагая, что это всего лишь учебное упражнение, рекомендуемый способ реализации
IDisposable
- добавить «уловку безопасности», чтобы гарантировать, что любые ресурсы не будут утилизироваться дважды:источник
readonly
семантике)В следующем примере показаны общие рекомендации по реализации
IDisposable
интерфейса. СсылкаИмейте в виду, что вам нужен деструктор (финализатор), только если у вас есть неуправляемые ресурсы в вашем классе. И если вы добавите деструктор, вы должны запретить Финализацию в Dispose , иначе это приведет к тому, что ваши объекты будут находиться в памяти в течение двух циклов мусора (Примечание: прочтите, как работает Финализация ). Ниже приведен пример.
источник
IDisposable
существует для того, чтобы предоставить вам средства для очистки неуправляемых ресурсов, которые не будут очищаться сборщиком мусора автоматически.Все ресурсы, которые вы «очищаете», являются управляемыми ресурсами, и поэтому ваш
Dispose
метод ничего не делает. Ваш класс не должен реализовыватьIDisposable
вообще. Сборщик мусора сам позаботится обо всех этих полях.источник
Вам нужно использовать одноразовый шаблон, как это:
источник
SafeHandle
(и подтипами). В случае управляемых ресурсов реализация правильной утилизации становится намного проще; Вы можете урезать код до простой реализацииvoid Dispose()
метода.Вам не нужно делать ваш
User
класс существом,IDisposable
так как класс не получает никаких неуправляемых ресурсов (файл, соединение с базой данных и т. Д.). Обычно мы помечаем классы так, какIDisposable
будто у них есть хотя бы одноIDisposable
поле или свойство. При реализацииIDisposable
лучше поставить его по типичной схеме Microsoft:источник
Idisposable реализуется всякий раз, когда вам нужна детерминированная (подтвержденная) сборка мусора.
При создании и использовании класса Users используйте блок «using», чтобы избежать явного вызова метода dispose:
конец созданного блока пользователя Объект Users будет удален неявным вызовом метода dispose.
источник
Я вижу много примеров шаблона Microsoft Dispose, который действительно является анти-шаблоном. Как многие отмечают, код в вопросе не требует IDisposable вообще. Но если вы собираетесь его реализовать, не используйте шаблон Microsoft. Лучшим ответом будет следовать предложениям в этой статье:
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
Единственное, что может быть полезно, - это отключить это предупреждение анализа кода ... https://docs.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs- 2017
источник