C# Is it possible to replicate the using syntax for others purposes?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I can reproduce it using Func<> like so :



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


However, this isn't quite the same because fcan't assign variables known by the caller.





I would like to be able to replicate using syntax to clean up some code.
Actual code



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);
}


What I'm attempting to have (or other syntaxe like the one of 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();
}
}
}









share|improve this question




















  • 1





    A workaround would be to implement a new class with IDisposable, but I feel it's a bit weird to use IDisposable for something else than memory management.

    – AXMIM
    Nov 23 '18 at 20:32











  • IDisposable is a contract that a lot of C# programmers have a problem with. Roughly, they never use for the first 2 years, then they get burned badly a couple of times and always use it. Then they learn what it does and use it when it make sense. According to the contract. So you can't predict what's going to happen, if you expect another programmer to use it. If it appears only in your own code then don't worry about it.

    – Hans Passant
    Nov 23 '18 at 20:44








  • 1





    Memory management is the one thing IDisposable is not used for -- we have the garbage collector for that. IDisposable is for deterministic cleanup of resources not tracked by the runtime. The "deterministically revert context" pattern isn't exactly the same thing as cleaning up resources, but it's a fairly common pattern that IDisposable does get used for. If my brain was working I'd cough up an example from the BCL, because I'm pretty sure it has a few.

    – Jeroen Mostert
    Nov 23 '18 at 20:46













  • @JeroenMostert You mean like WindowsImpersonationContext and possibly DbTransaction?

    – BACON
    Nov 23 '18 at 21:03











  • The using block is inherently just a shortcut for a try...finally block + a null check. It sounds like your Context class should simply implement IDisposeable, with the sole operation of calling this.PutBackOriginalIsolationLevel(). By definition of needing that call, it has "some unmanaged resources that require cleanup." Wich is exactly the purpose of IDisposeable. It is even a note to anybody using your Context class (possibly in their classes) to also Implement IDiposeable to relay the Dispose call.

    – Christopher
    Nov 23 '18 at 21:03




















0















I can reproduce it using Func<> like so :



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


However, this isn't quite the same because fcan't assign variables known by the caller.





I would like to be able to replicate using syntax to clean up some code.
Actual code



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);
}


What I'm attempting to have (or other syntaxe like the one of 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();
}
}
}









share|improve this question




















  • 1





    A workaround would be to implement a new class with IDisposable, but I feel it's a bit weird to use IDisposable for something else than memory management.

    – AXMIM
    Nov 23 '18 at 20:32











  • IDisposable is a contract that a lot of C# programmers have a problem with. Roughly, they never use for the first 2 years, then they get burned badly a couple of times and always use it. Then they learn what it does and use it when it make sense. According to the contract. So you can't predict what's going to happen, if you expect another programmer to use it. If it appears only in your own code then don't worry about it.

    – Hans Passant
    Nov 23 '18 at 20:44








  • 1





    Memory management is the one thing IDisposable is not used for -- we have the garbage collector for that. IDisposable is for deterministic cleanup of resources not tracked by the runtime. The "deterministically revert context" pattern isn't exactly the same thing as cleaning up resources, but it's a fairly common pattern that IDisposable does get used for. If my brain was working I'd cough up an example from the BCL, because I'm pretty sure it has a few.

    – Jeroen Mostert
    Nov 23 '18 at 20:46













  • @JeroenMostert You mean like WindowsImpersonationContext and possibly DbTransaction?

    – BACON
    Nov 23 '18 at 21:03











  • The using block is inherently just a shortcut for a try...finally block + a null check. It sounds like your Context class should simply implement IDisposeable, with the sole operation of calling this.PutBackOriginalIsolationLevel(). By definition of needing that call, it has "some unmanaged resources that require cleanup." Wich is exactly the purpose of IDisposeable. It is even a note to anybody using your Context class (possibly in their classes) to also Implement IDiposeable to relay the Dispose call.

    – Christopher
    Nov 23 '18 at 21:03
















0












0








0








I can reproduce it using Func<> like so :



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


However, this isn't quite the same because fcan't assign variables known by the caller.





I would like to be able to replicate using syntax to clean up some code.
Actual code



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);
}


What I'm attempting to have (or other syntaxe like the one of 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();
}
}
}









share|improve this question
















I can reproduce it using Func<> like so :



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


However, this isn't quite the same because fcan't assign variables known by the caller.





I would like to be able to replicate using syntax to clean up some code.
Actual code



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);
}


What I'm attempting to have (or other syntaxe like the one of 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();
}
}
}






c#






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 21:57









T.S.

10.3k103554




10.3k103554










asked Nov 23 '18 at 20:30









AXMIMAXMIM

1,58811331




1,58811331








  • 1





    A workaround would be to implement a new class with IDisposable, but I feel it's a bit weird to use IDisposable for something else than memory management.

    – AXMIM
    Nov 23 '18 at 20:32











  • IDisposable is a contract that a lot of C# programmers have a problem with. Roughly, they never use for the first 2 years, then they get burned badly a couple of times and always use it. Then they learn what it does and use it when it make sense. According to the contract. So you can't predict what's going to happen, if you expect another programmer to use it. If it appears only in your own code then don't worry about it.

    – Hans Passant
    Nov 23 '18 at 20:44








  • 1





    Memory management is the one thing IDisposable is not used for -- we have the garbage collector for that. IDisposable is for deterministic cleanup of resources not tracked by the runtime. The "deterministically revert context" pattern isn't exactly the same thing as cleaning up resources, but it's a fairly common pattern that IDisposable does get used for. If my brain was working I'd cough up an example from the BCL, because I'm pretty sure it has a few.

    – Jeroen Mostert
    Nov 23 '18 at 20:46













  • @JeroenMostert You mean like WindowsImpersonationContext and possibly DbTransaction?

    – BACON
    Nov 23 '18 at 21:03











  • The using block is inherently just a shortcut for a try...finally block + a null check. It sounds like your Context class should simply implement IDisposeable, with the sole operation of calling this.PutBackOriginalIsolationLevel(). By definition of needing that call, it has "some unmanaged resources that require cleanup." Wich is exactly the purpose of IDisposeable. It is even a note to anybody using your Context class (possibly in their classes) to also Implement IDiposeable to relay the Dispose call.

    – Christopher
    Nov 23 '18 at 21:03
















  • 1





    A workaround would be to implement a new class with IDisposable, but I feel it's a bit weird to use IDisposable for something else than memory management.

    – AXMIM
    Nov 23 '18 at 20:32











  • IDisposable is a contract that a lot of C# programmers have a problem with. Roughly, they never use for the first 2 years, then they get burned badly a couple of times and always use it. Then they learn what it does and use it when it make sense. According to the contract. So you can't predict what's going to happen, if you expect another programmer to use it. If it appears only in your own code then don't worry about it.

    – Hans Passant
    Nov 23 '18 at 20:44








  • 1





    Memory management is the one thing IDisposable is not used for -- we have the garbage collector for that. IDisposable is for deterministic cleanup of resources not tracked by the runtime. The "deterministically revert context" pattern isn't exactly the same thing as cleaning up resources, but it's a fairly common pattern that IDisposable does get used for. If my brain was working I'd cough up an example from the BCL, because I'm pretty sure it has a few.

    – Jeroen Mostert
    Nov 23 '18 at 20:46













  • @JeroenMostert You mean like WindowsImpersonationContext and possibly DbTransaction?

    – BACON
    Nov 23 '18 at 21:03











  • The using block is inherently just a shortcut for a try...finally block + a null check. It sounds like your Context class should simply implement IDisposeable, with the sole operation of calling this.PutBackOriginalIsolationLevel(). By definition of needing that call, it has "some unmanaged resources that require cleanup." Wich is exactly the purpose of IDisposeable. It is even a note to anybody using your Context class (possibly in their classes) to also Implement IDiposeable to relay the Dispose call.

    – Christopher
    Nov 23 '18 at 21:03










1




1





A workaround would be to implement a new class with IDisposable, but I feel it's a bit weird to use IDisposable for something else than memory management.

– AXMIM
Nov 23 '18 at 20:32





A workaround would be to implement a new class with IDisposable, but I feel it's a bit weird to use IDisposable for something else than memory management.

– AXMIM
Nov 23 '18 at 20:32













IDisposable is a contract that a lot of C# programmers have a problem with. Roughly, they never use for the first 2 years, then they get burned badly a couple of times and always use it. Then they learn what it does and use it when it make sense. According to the contract. So you can't predict what's going to happen, if you expect another programmer to use it. If it appears only in your own code then don't worry about it.

– Hans Passant
Nov 23 '18 at 20:44







IDisposable is a contract that a lot of C# programmers have a problem with. Roughly, they never use for the first 2 years, then they get burned badly a couple of times and always use it. Then they learn what it does and use it when it make sense. According to the contract. So you can't predict what's going to happen, if you expect another programmer to use it. If it appears only in your own code then don't worry about it.

– Hans Passant
Nov 23 '18 at 20:44






1




1





Memory management is the one thing IDisposable is not used for -- we have the garbage collector for that. IDisposable is for deterministic cleanup of resources not tracked by the runtime. The "deterministically revert context" pattern isn't exactly the same thing as cleaning up resources, but it's a fairly common pattern that IDisposable does get used for. If my brain was working I'd cough up an example from the BCL, because I'm pretty sure it has a few.

– Jeroen Mostert
Nov 23 '18 at 20:46







Memory management is the one thing IDisposable is not used for -- we have the garbage collector for that. IDisposable is for deterministic cleanup of resources not tracked by the runtime. The "deterministically revert context" pattern isn't exactly the same thing as cleaning up resources, but it's a fairly common pattern that IDisposable does get used for. If my brain was working I'd cough up an example from the BCL, because I'm pretty sure it has a few.

– Jeroen Mostert
Nov 23 '18 at 20:46















@JeroenMostert You mean like WindowsImpersonationContext and possibly DbTransaction?

– BACON
Nov 23 '18 at 21:03





@JeroenMostert You mean like WindowsImpersonationContext and possibly DbTransaction?

– BACON
Nov 23 '18 at 21:03













The using block is inherently just a shortcut for a try...finally block + a null check. It sounds like your Context class should simply implement IDisposeable, with the sole operation of calling this.PutBackOriginalIsolationLevel(). By definition of needing that call, it has "some unmanaged resources that require cleanup." Wich is exactly the purpose of IDisposeable. It is even a note to anybody using your Context class (possibly in their classes) to also Implement IDiposeable to relay the Dispose call.

– Christopher
Nov 23 '18 at 21:03







The using block is inherently just a shortcut for a try...finally block + a null check. It sounds like your Context class should simply implement IDisposeable, with the sole operation of calling this.PutBackOriginalIsolationLevel(). By definition of needing that call, it has "some unmanaged resources that require cleanup." Wich is exactly the purpose of IDisposeable. It is even a note to anybody using your Context class (possibly in their classes) to also Implement IDiposeable to relay the Dispose call.

– Christopher
Nov 23 '18 at 21:03














1 Answer
1






active

oldest

votes


















2














As others have commented, you can use using and IDisposable to achieve this:



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


And, you can use it as shown here:



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

get3 = _context.Get3(param);


The Disposble method will always be called, since it is essentially implemented like a try-finally. You can uncomment the throw and verify yourself.



Note: Disposable.Create can be found by using System.Reactive. Or, you can implement your own:



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();
}
}





share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452631%2fc-sharp-is-it-possible-to-replicate-the-using-syntax-for-others-purposes%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    As others have commented, you can use using and IDisposable to achieve this:



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


    And, you can use it as shown here:



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

    get3 = _context.Get3(param);


    The Disposble method will always be called, since it is essentially implemented like a try-finally. You can uncomment the throw and verify yourself.



    Note: Disposable.Create can be found by using System.Reactive. Or, you can implement your own:



    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();
    }
    }





    share|improve this answer




























      2














      As others have commented, you can use using and IDisposable to achieve this:



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


      And, you can use it as shown here:



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

      get3 = _context.Get3(param);


      The Disposble method will always be called, since it is essentially implemented like a try-finally. You can uncomment the throw and verify yourself.



      Note: Disposable.Create can be found by using System.Reactive. Or, you can implement your own:



      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();
      }
      }





      share|improve this answer


























        2












        2








        2







        As others have commented, you can use using and IDisposable to achieve this:



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


        And, you can use it as shown here:



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

        get3 = _context.Get3(param);


        The Disposble method will always be called, since it is essentially implemented like a try-finally. You can uncomment the throw and verify yourself.



        Note: Disposable.Create can be found by using System.Reactive. Or, you can implement your own:



        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();
        }
        }





        share|improve this answer













        As others have commented, you can use using and IDisposable to achieve this:



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


        And, you can use it as shown here:



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

        get3 = _context.Get3(param);


        The Disposble method will always be called, since it is essentially implemented like a try-finally. You can uncomment the throw and verify yourself.



        Note: Disposable.Create can be found by using System.Reactive. Or, you can implement your own:



        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();
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 23 '18 at 21:26









        Xiaoy312Xiaoy312

        11.7k12234




        11.7k12234
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452631%2fc-sharp-is-it-possible-to-replicate-the-using-syntax-for-others-purposes%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            If I really need a card on my start hand, how many mulligans make sense? [duplicate]

            Alcedinidae

            Can an atomic nucleus contain both particles and antiparticles? [duplicate]