【问题标题】:Why does class implementing IDispose not have OnDisposed override?为什么实现 IDispose 的类没有 OnDisposed 覆盖?
【发布时间】:2016-10-25 10:42:20
【问题描述】:

我有一个具有以下定义的类,我希望它具有 Dispose 方法的覆盖:

编辑

原来有一个 Dispose() 方法,但它不是一个覆盖。我期待一个覆盖。这可能是一个无效的问题......但为什么它不是一个覆盖?

public class MyClient : IMyClient2
{
    public void Dispose()
    {
        Dispose(true);
    }

    private void Dispose(bool disposing)
    {
        if(disposing)
        {
            Stop();
        }
    }
}

它所扩展的接口,以及它的后续接口,定义为:

public interface IMyClient2 : IMyClient
{
    // one or two methods
}

public interface IMyClient : IDisposable
{
    // a bunch of methods
}

我认为实现 IDisposable 需要我的类具有 Dispose() 覆盖。但它没有,我不知道我需要做什么才能做到这一点。

我需要做什么才能正确处理我的类的实例?

【问题讨论】:

  • 我不是很明白这个问题,你的意思是不用实现IDisposable.Dispose()就可以编译这段代码吗?那应该是不可能的。
  • 使用上面显示的小代码MyClient 必须实现IDisposables Dispose 方法。如果没有并且没有编译器错误,那么您还没有显示所有代码。
  • 嗯,这绝对是可能的。这是我从 repo 中提取、构建并运行的代码。它运行良好。我以为我会使用方便的 IDisposable 实现来覆盖 IDispose 方法来解决我遇到的问题,但令我惊讶的是没有 Dispose 覆盖(ReSharper 告诉我)。
  • @DaveDev - 你确定这是层次结构吗?你能显示实际的课程吗?您是否有一些基类,而不仅仅是接口?
  • 不,这是不可能的。您不能定义要在类型上实现的接口,然后不能在您的类型上实现/定义这些方法。代码不会编译。您还没有显示所有代码。

标签: c# idisposable


【解决方案1】:

如果你的类真的像问题中那样实现了这些接口,你应该得到一个编译错误

MyClass 没有实现接口成员IDisposable.Dispose()

当您添加 public void Dispose() 实现时,这将得到解决


更新:

原来有一个 Dispose() 方法,但它不是一个覆盖。我期待一个覆盖。这可能是一个无效的问题......但为什么它不是一个覆盖?

override 关键字用于覆盖基类中的abstractvirtual 方法。当您实现接口时,不需要关键字。由 MSDN 在override keyword 上声明:

需要 override 修饰符来扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现。

如果您要扩展基类而不是接口,并且 Dispose 方法将具有 abstractvirtual 关键字,则您可以 override 它在派生类中实现。

objectToString()为例:

public class Object
{       
    // Returns a String which represents the object instance.  The default
    // for an object is to return the fully qualified name of the class.
    // 
    public virtual String ToString()
    {
        return GetType().ToString();
    }    
}

如果在您的班级中,您将添加以下功能:

public override string ToString()
{
    // Add your implementation
}

【讨论】:

  • 这是正确答案。我正在寻找替代方案,但找不到。原来 Dispose() 方法在那里,但我没有看到它。正如我在上面的评论中所说,我只是从 repo 中删除了这个,我没有看到方法。很抱歉给您带来麻烦。
【解决方案2】:

我认为实现 IDisposable 需要我的类具有 Dispose() 覆盖。但它没有,我不知道我需要做些什么才能做到这一点。

改变基类

public class MyClient : IMyClient2
{
    public virtual void Dispose()
    {
        Dispose(true);
    }
}

你的新类型

public class MyClient2 : MyClient
{
    public override void Dispose()
    {
        // add your dispose information
        base.Dispose(true);
    }
}

这将允许派生自您的 MyClient 类型的类型也实现自己的 Dispose 方法覆盖。不需要在覆盖类型中实现 Dispose。如果你想这样做,那么你必须使用抽象的 Dispose 方法将你的 MyClient 类标记为抽象。

改变基类

public abstract class MyClient : IMyClient2
{
    public abstract void Dispose()
    {
        Dispose(true);
    }
}

你的新类型

public class MyClient2 : MyClient
{
    public override void Dispose()
    {
        // add your dispose information
        base.Dispose(true);
    }
}

【讨论】:

    【解决方案3】:

    我认为实现 IDisposable 需要我的类具有 Dispose() 覆盖。但它没有,我不知道我需要做什么才能做到这一点。

    没有。接口不使用abstract/virtual/override 关键字。作者实现了接口,没有重写任何虚方法。

    注意 IDisposable 定义中没有 virtual/abstract

    public interface IDisposable
    {
        void Dispose();
    }
    

    为什么不是覆盖?

    作者本可以选择遵循最佳实践并提供protected virtual void Dispose(bool disposing),但也没有选择。
    我猜他没想到你会想扩展课程。

     

    你现在能做什么?

    如果您有权更改代码,那么您可以继续并根据需要实现 IDisposable。例如。 https://msdn.microsoft.com/en-us/library/ms244737.aspx

    如果您无法更改代码,那么您仍然可以选择。您可以使用组合/装饰器模式来提供您自己的 Dispose 实现。

    您可以从MyClient 继承,然后自己显式提供 Dispose 的实现。当对象被释放时,会调用与接口相关联的方法。
    这实际上与覆盖相同。例如:

    public class MyClient2 : MyClient
    {
        void IDisposable.Dispose()
        {
            base.Dispose();
            //Do whatever you like here.
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      • 2020-05-12
      • 1970-01-01
      相关资源
      最近更新 更多