c# - 具体类型*可能*是一次性的时的多态性

标签 c# polymorphism idisposable

如果依赖容器或数据访问工厂可以返回可能实现IDisposable的类型,那么检查和处理它是否应该是客户端的责任?在我下面的代码中,一个数据类实现了 IDisposable 而另一个没有。数据访问工厂可以返回任何一个。

    private static void TestPolymorphismWithDisposable()
    {
        // Here we don't know if we're getting a type that implements IDisposable, so
        // if we just do this, then we won't be disposing of our instance.
        DataAccessFactory.Resolve().Invoke();

        // Do we just have to do something like this?
        IFoo foo = DataAccessFactory.Resolve();
        foo.Invoke();
        var fooAsDisposable = foo as IDisposable;
        if (fooAsDisposable != null) { fooAsDisposable.Dispose(); }
    }

我问的原因是,这似乎给客户端代码带来了负担,必须处理这个问题,以及如何让客户端知道,在构建 API 时,他们可能需要调用处理?有没有更好的方法来处理客户端不必检查 IDisposable 的情况?

为了完整的工作示例,这里是其他类:

public interface IFoo
{
    void Invoke();
}

public class DataAccessBaseNotDisposable : IFoo
{
    public void Invoke()
    {
        Console.WriteLine("In Invoke() in DataAccessBaseNotDisposable.");
    }
}

public class DataAccessBaseDisposable : IFoo, IDisposable
{
    public void Invoke()
    {
        Console.WriteLine("Invoke() in DataAccessBaseDisposable.");
    }

    public void Dispose()
    {
        Console.WriteLine("In Dispose() in DataAccessBaseDisposable.");
    }
}

public static class DataAccessFactory
{
    public static IFoo Resolve()
    {
        return new DataAccessBaseDisposable();
        //return new DataAccessBaseNotDisposable();
    }
}

最佳答案

编辑:最好的解决方案是始终返回一个 IDisposable 对象,即使该对象不需要被释放。这样,框架用户就不必一直检查 IDisposable。

你的框架看起来像这样:

public interface IFoo : IDisposable
{
    void Invoke();
}

public class DataAccessBase : IFoo
{
    public void Invoke()
    {
        Console.WriteLine("In Invoke() in DataAccessBase.");
    }

    public void Dispose()
    {
        Console.WriteLine("In Dispose() in DataAccessBase.");
    }
}

public static class DataAccessFactory
{
    public static IFoo Resolve()
    {
        return new DataAccessBase();
    }
}

它会如您所料地被消耗掉:

private static void TestPolymorphismWithDisposable()
{
    using(IFoo foo = DataAccessFactory.Resolve())
    {
        foo.Invoke();
    }
}

但是,如果您是用户,并且遇到可能实现也可能不实现 IDisposable 的结果,您需要按如下方式使用它:

private static void TestPolymorphismWithDisposable()
{
    IFoo foo = DataAccessFactory.Resolve();

    using(foo as IDisposable)
    {
        foo.Invoke(); //This is always executed regardless of whether IDisposable is implemented

        //Dispose is called if IDisposable was implemented
    }
}

查看这些问题:Using statement with a null objectUsing 'as IDisposable' in a using block

关于c# - 具体类型*可能*是一次性的时的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20953911/

相关文章:

c# - 使用 ADAL JS 的 Azure AD Graph API 不记名 token

c# - 拥有一次性字段的类型应该是一次性的。如何解决这个警告?

java - 从接口(interface)类型而不是类类型声明,似乎不是多态的或更一般的

c# - 运算符重载多态返回泛型集合

c# - 在实现 IDisposable 的类上正确使用 Dispose 方法

.net - 处理 StreamWriter 而不在一行中声明变量

c# - 如何使用 IP 地址通过 SSL 协议(protocol)访问 WCF?

c# - 如何在 MVC 中自定义脚手架模板和更改 .cs.t4 文件

c# - 文件未正确读取 Visual Studio 中 ASPX 文件的输入

polymorphism - 在函数签名中包含模块签名和该模块类型的值