我正在尝试创建一个在使用时看起来如下的方法:
Dialog (var d = new MyDialog())
{
d.DoSomethingToAVisibleDialogThatAppearedInTheDialog(); //Call
}
就像“使用”一样,它会处理析构函数,但我想在Dialog中添加更多内容,它将处理我的IDialog接口。
答案 0 :(得分:3)
您可以创建类似以下的类:
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
}
答案 1 :(得分:1)
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());
答案 2 :(得分:0)
我写了一个名为ResourceReleaser<T>的课程。
典型用法:
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