c# - 在不修改类(或了解实现细节)的情况下扩展类的模式 (c#)

标签 c# .net design-patterns inheritance

我正在修改位于两个既定层之间的一些代码,并且无法确定最佳设计是什么。

目前代码调用一个文件访问库,并返回一个对象给调用者。我需要扩展返回的对象以添加一些自定义处理功能。我无权访问传递对象的定义(例如,有些是文件流)

如果我可以创建一个行为类似于基础实例的子实例,并且可以从基础实例创建,但它有一些隐藏的额外功能,那将节省我很多工作。在不知道基类实现细节的情况下能做到吗?

代码形式看起来很像这样:

private class FileObjectWithDispose : FileObject, IDisposable
{//voidaction is a delegate, this is .net 2.0
    private VoidAction _disposeCallback;

public static FileObjectWithDispose wrapFile(FileObject unWrappedFile, VoidAction DisposeAction)
{//Implementation missing, this is the crux of what I don't know how to do
    FileObjectWithDispose wrappedFile = new FileObjectWithDispose(unWrappedFile);
    wrappedFile._disposeCallback = DisposeAction;
    return wrappedFile;
}

private FileObjectWithDispose()
    : base(null, null)//base class does not have a default constructor
{
    throw new NotImplementedException("FileObjectWithDispose is a wrapper class which is intended only to be cast from a filestream.");
}

private void Dispose()
{
    _disposeCallback();
    base.Dispose();
}

示例调用如下所示:

Connect(file, username, password, domain);
return FileObjectWithDispose.wrapFile(OpenFile(path), () => { Disconnect(file, username); });

我遇到的主要困难是,如果可能的话,如果基类没有实现允许自身被装饰的接口(interface),我该如何获取一个基类实例并创建一个装饰实例? 有什么想法可以完成这项任务吗?

谢谢!

最佳答案

装饰器模式是必经之路。

  1. 创建接口(interface) ICustomDisposeAction(示例名称)
  2. 使用您想要对其执行 DisposeAction 的所有那些可能的类来实现此接口(interface)。

    FileObjectWithDispose:文件对象、IDisposable、ICustomDisposeAction

  3. 创建另一个类 Decorator,它也实现了 ICustomDisposeAction。通过装饰器的构造函数传递原始基类,然后在其上调用装饰器的DisposeAction

public class Decorator : ICustomDisposeAction
{
  public FileObject wrappedFile { get; set; } 
  public Decorator(FileObject unWrappedFile,...)
  {
    wrappedFile = unWrappedFile;
    //Do your custom dispose here
  }
} 
  1. 在那些需要自定义方式处理对象的情况下,创建装饰器对象并进行自定义处理!

希望这对您有所帮助。

关于c# - 在不修改类(或了解实现细节)的情况下扩展类的模式 (c#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12274960/

相关文章:

c# - 对于 C# 中的多平台 GUI 应用程序,我有哪些选择?

c# - 什么是单元测试范围?

.net - F# Seq 的一个实现问题

C# System.InvalidCastException

c# - 不同类型的列表列表

java - 主循环和单独线程哪个更好?

单元测试期间的 C# 扩展方法奇怪

c# - 如何使用 LINQ 从集合的开头查找子集?

java - 桥梁设计模式中抽象的含义

design-patterns - Scala 中的访问者模式