可正确实施ID

问题描述 投票:133回答:8

在我的课程中,我实现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,在'User'上提供Dispose(bool)的可重写实现,或将类型标记为密封。调用Dispose(false)仅应清除本机资源。调用Dispose(true)应该同时清除托管资源和本机资源。 stman User.cs 10

供参考:CA1063: Implement IDisposable correctly

我已经阅读了本页面,但恐怕我真的不明白在这里需要做什么。

如果任何人都可以用更多的语言解释问题是什么和/或应该如何实现IDisposable,那将真的有帮助!

c# .net memory-management memory-leaks garbage-collection
8个回答
105
投票

这将是正确的实现,尽管在发布的代码中我看不到需要处理的任何内容。您只需要在以下情况下实现IDisposable

  1. 您拥有不受管理的资源
  2. 您要坚持引用那些本身就是一次性的东西。

您发布的代码中的任何内容都不需要处理。

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()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing) 
        {
            // free managed resources
        }
        // free native resources if there are any.
    }
}

55
投票

首先,您不需要“清理” stringint,它们会由垃圾收集器自动处理。 Dispose中唯一需要清除的是实现IDisposable的非托管资源或托管资源。

但是,假设这只是一个学习练习,实现IDisposable推荐方法是添加“安全陷阱”以确保不会两次处置任何资源:]]

public void Dispose()
{
    Dispose(true);

    // Use SupressFinalize in case a subclass 
    // of this type implements a finalizer.
    GC.SuppressFinalize(this);   
}
protected virtual void Dispose(bool disposing)
{
    if (!_disposed)
    {
        if (disposing) 
        {
            // Clear all property values that maybe have been set
            // when the class was instantiated
            id = 0;
            name = String.Empty;
            pass = String.Empty;
        }

        // Indicate that the instance has been disposed.
        _disposed = true;   
    }
}

39
投票

以下示例显示了实现IDisposable接口的一般最佳实践。 Reference


14
投票

IDisposable的存在为您提供了一种清理unmanaged


13
投票

您需要像这样使用一次性模式


9
投票

您无需将您的User类设为IDisposable,因为该类不获取


3
投票

无论何时您需要确定性(已确认)垃圾回收,Idisposable都是实现。


0
投票

我看到了很多Microsoft Dispose模式的例子,这实际上是一种反模式。正如许多人指出的那样,问题中的代码根本不需要IDisposable。但是,如果要在哪里实现它,请不要使用Microsoft模式。更好的答案是遵循本文中的建议:

© www.soinside.com 2019 - 2024. All rights reserved.