如何创建一个使用类似于c#中使用的配置文件的扩展方法?

本文关键字:何创建 配置文件 扩展 方法 类似于 一个 创建 | 更新日期: 2023-09-27 17:50:24

我正在尝试创建一个方法,使用时看起来像以下:

Dialog (var d = new MyDialog())
{
    d.DoSomethingToAVisibleDialogThatAppearedInTheDialog(); //Call
}

像"using"一样,它会处理析构函数,但是我想在Dialog中添加更多的东西,它将处理我的IDialog接口。

如何创建一个使用类似于c#中使用的配置文件的扩展方法?

您可以像下面这样创建一个类:

class DisposableWrapper<T> : where T : IDisposable {
    T _wrapped;
    private bool _disposed;
    public DisposableWrapper(T wrapped) {
        _wrapped = wrapped;
    }
    public T Item {
        get { return _wrapped; }
    }
    public ~DisposableWrapper()
    {
        Dispose(false);
        GC.SuppressFinalize(this);
    }
    public void Dispose() {
        Dispose(true);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;
        if (disposing) {
            _disposed = true;             
            ((IDisposable)_wrapped).Dispose();
            // do extra stuff
        }
    }
}

然后像这样使用:

using (var wrapper = new DisposableWrapper(new Dialog()) {
    Dialog d = wrapper.Item;
    // do stuff
}

using是一种语言特性,并且特定于IDisposable。它不能针对不同的语义直接扩展。你所尝试的基本上是为语言添加一个新特性,这是不可能的。

最好的选择通常是提供一个动作,理想情况下是在具有new()约束的泛型方法中。

public static void Dialog<T>(Action<T> action) where T: IDialog, new()
{
    var d = new T();
    try
    {
        action(d);
    }
    finally
    {
       var idialog = d as IDialog;
       if (idialog != null)
       {
           idialog.Dispose(); // Or whatever IDialog method(s) you want
       }
    }
}

你可以这样做:

Dialog(d => d.DoSomethingToAVisibleDialogThatAppearedInTheDialog());

我编写了一个类来做这个,叫做ResourceReleaser

典型用途:

public class StreamPositionRestorer : ResourceReleaser<long>
{
    public StreamPositionRestorer(Stream s) : base(s.Position, x => s.Seek(x)) { }
}

这个例子的最终结果是:

using (var restorer = new StreamPositionRestorer(stm)) {
    // code that mucks with the stream all it wants...
}
// at this point the stream position has been returned to the original point