Как создать метод расширения, который использует профиль, аналогичный использованию в C # - PullRequest
1 голос
/ 18 апреля 2011

Я пытаюсь создать метод, который при использовании выглядит следующим образом:

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

Как и «использование», оно будет обрабатывать деструктор, но я хочу добавить больше вещей в диалог, который будет обрабатывать мой интерфейс IDialog.

Ответы [ 3 ]

3 голосов
/ 18 апреля 2011

Вы можете создать класс, подобный следующему:

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 голос
/ 18 апреля 2011

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());
0 голосов
/ 19 апреля 2011

Я написал класс, который делает это с именем 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...