C#是否可以将using语法复制用于其他目的?

时间:2018-11-23 20:30:49

标签: c#

我可以像这样使用Func<>复制它:

public SimilarSyntax<T>(Func<T> f) 
{
    Begin(); 
    var result = f(); 
    End(); 
    return result;
}

但是,这并不完全相同,因为f无法分配调用方已知的变量。


我希望能够复制using语法来清理一些代码。
实际代码

void SomeProcedure(object param)
{
    Class1 get1;
    Class2 get2;
    ...
    ClassN getN;

    try
    {
        _context.SetReadUnCommitted();
        get1 _context.Get1(param);
        ...

        get2 _context.Get2(param);
    }
    finally
    {
        _context.PutBackOriginalIsolationLevel();
    }

    _context.Get3(param);
}

我要尝试的内容(或其他语法,例如using中的一种)

void SomeProcedure(object param)
{
    Class1 get1;
    Class2 get2;
    ...
    ClassN getN;

    _context.ExecuteInReadUnCommitted
    (
       () =>
        {
            get1 = _context.Get1(param);
            get2 = _context.Get2(param);
        }
    );

    _context.Get3(param);
}

public class Context
{
    public void ExecuteInReadUnCommitted(Action action)
    {
        try
        {
            this.SetReadUnCommitted();
            action();
        }
        finally
        {
            this.PutBackOriginalIsolationLevel();
        }
    }
} 

1 个答案:

答案 0 :(得分:2)

正如其他人所评论的那样,您可以使用usingIDisposable来实现:

public class Context
{   
    public IDisposable ReadUnCommitted()
    {
        SetReadUnCommitted();
        return Disposable.Create(PutBackOriginalIsolationLevel);
    }
}

而且,您可以按如下所示使用它:

using (context.ReadUnCommitted())
{
    get1 = _context.Get1(param);
    // throw new NotImplementedException();
    get2 = _context.Get2(param);
}

get3 = _context.Get3(param);

将始终调用Disposble方法,因为它实际上是like a try-finally实现的。您可以取消注释throw并验证自己。

注意:using System.Reactive可以找到Disposable.Create。或者,您可以实现自己的:

public static class DisposableEx
{
    public static IDisposable Create(Action dispose)
    {
        return new DisposableImpl(dispose);
    }

    private class DisposableImpl : IDisposable
    {
        private readonly Action dispose;

        public DisposableImpl(Action dispose)
        {
            this.dispose = dispose;
        }

        public void Dispose() => dispose?.Invoke();
    }
}