Как упростить (сократить) запись?
От: Аноним  
Дата: 20.02.11 09:57
Оценка:
try
{
    CanSomethingDo = false;
    foo(); // на нее влияет глобальный флаг CanSomethingDo
}
finally
{
    CanSomethingDo = true;
}


Хочется короче как-то, ближе к:

CanSomethingDo = false;
foo(); // на нее влияет глобальный флаг CanSomethingDo
CanSomethingDo = true;


или еще короче, как в си++ с временным структурками и конструкторами/деструкторами:

{
    can_something_do csd(true);
    foo();
    // в деструкторе false
}


чувствуется, что можно что-то с using() замутить, но не придумаю как, и класс лишний с IDisposable рождать совсем не хочется
Re: Как упростить (сократить) запись?
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 20.02.11 10:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>try
А>{
А>    CanSomethingDo = false;
А>    foo(); // на нее влияет глобальный флаг CanSomethingDo
А>}
А>finally
А>{
А>    CanSomethingDo = true;
А>}
А>


А>Хочется короче как-то, ближе к:


А>
А>CanSomethingDo = false;
А>foo(); // на нее влияет глобальный флаг CanSomethingDo
А>CanSomethingDo = true;
А>


Ваш код выглядит немного подозрительно. Вы уверены, что флаг CanSomethingDo должен выставляться именно в блоке finally, а не после метода foo? В этом случае, этот флаг станет true даже в случае исключения в методе foo.

Ну, если вам нужно именно это, то наш камрад _FRED_ у себя в блоге в статейке "Парные методы" как раз об этом писал. Создаем следующие классы:

public static class Disposable
{
  public static IDisposable New(Action dispose) {
    return new ActionDisposable(dispose);
  }
 
  [Serializable]
  [DebuggerDisplay("{ Action != null ? \"<Action>\" : \"<Action (Empty)>\" }")]
  private sealed class ActionDisposable : IDisposable
  {
    public ActionDisposable(Action action) {
      Action = action;
    }
 
    private Action Action { get; set; }
 
    public void Dispose() {
      if(Action != null) {
        Action();
        Action = null;
      }//if
    }
  }
}


И потом в вашем классе (или там, где лежит ваш флаг), добавляем следующий метод:
  public static IDisposable DoSomething() {
    CanDoSomething = false;
    return Disposable.New(()=>CanDoSomething = true);
  }


Использование будет таким:
using (DoSomething())
{
    Console.WriteLine("Inside using statement.");
}


Так что С++ идиома RAII присутствует и в C#, просто она немного по другому реализовывается.

@_FRED_
Re: Как упростить (сократить) запись?
От: ylem  
Дата: 20.02.11 10:25
Оценка: 1 (1)
А>чувствуется, что можно что-то с using() замутить, но не придумаю как, и класс лишний с IDisposable рождать совсем не хочется

Я вот такой костыль изобрел:
using (new TryFinally(() => graphics.SetClip(ClientRect), graphics.ResetClip))
{
...
}
Re[2]: Как упростить (сократить) запись?
От: Аноним  
Дата: 20.02.11 10:55
Оценка:
Здравствуйте, SergeyT., Вы писали:

Спасибо! Чувствовал что, что-то такое должно быть с using
Да именно в finally, его нормальное значение true, но в целях оптимизации иногда надо сказать false, чтобы то, что делают многие foo() сделать потом одним залпом (так быстрее) Так что цель во что бы то ни стало вернуть флаг назад
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.