Как заблокировать / разблокировать поле во время выполнения в C #?

2

Можно ли заблокировать/разблокировать поля или объекты во время выполнения при записи? Другими словами, что-то вроде изменения объектов на чтение только временно во время выполнения...

Например:

int x = 5; // x is 5  
LockObject(x);  
x = 7; // no change  
UnlockObject(x);  
x = 10; // x is 10

Если вы не можете дать мне несколько возможных решений?

  • 0
    Есть ли здесь какие-то нити? Предположим, что поле заблокировано в одном потоке. Может ли другой поток ждать, пока он разблокируется?
Теги:
locking
readonly

3 ответа

6
Лучший ответ

Вы можете использовать аксессоры для этого...

public class X
{
    private bool locked = false;

    private int lockedVar;
    public int LockedVar
    {
        get { return lockedVar; }
        set { if (!locked) lockedVar = value; }
    }

    public void LockObject() { locked = true; }
    public void UnlockObject() { locked = false; }
}
  • 2
    Я знаю, что это отличается от вопроса, но для протокола я считаю, что было бы лучше выбросить исключение, чем просто отбросить изменение.
  • 0
    @Marc: я думал о том же, но это заставило бы клиентский код обрабатывать исключения как часть его логики, которую обычно осуждают. Вы все еще хотели бы исключение, но чтобы помочь клиенту избежать перехвата исключений, можно было бы ввести свойство IsLocked только для чтения, которое можно было бы оценить, таким образом избегая выброса при попытке изменить заблокированное значение.
Показать ещё 3 комментария
1

Оберните его в свойство, а затем используйте логический флаг как "блокировку".

Вы также можете использовать struct для обработки этого типа логики.

public struct LockableInt
{
    private int _value;
    public bool Locked;

    public void Lock(bool locked) {Locked = locked;}

    public int Value
    {
        get 
        { return _value; }
        set 
        { if (!Locked) _value = value; }
    }

    public override string ToString()
    {
        return _value.ToString();
    }
}

Пример кода клиента:

public static void RunSnippet()
{
    LockableInt li = new LockableInt();
    li.Value = 5;
    Console.WriteLine(li.ToString());
    li.Lock(true);
    li.Value = 6;
    Console.WriteLine(li.ToString());
    li.Lock(false);
    li.Value = 7;
    Console.WriteLine(li.ToString());

}

Вывод:

5 5 7 Нажмите любую клавишу, чтобы продолжить...

  • 0
    Изменяемые структуры являются почти всегда очень плохой идеей , если вы точно не знаете , что вы делаете. И даже тогда это рискованно.
  • 0
    @Marc Gravell: я бы пошел дальше и сказал: «И даже тогда это плохая идея».
Показать ещё 3 комментария
0

Спасибо всем за помощь. Вот более обобщенная альтернатива.
Я решил, что было бы удобнее использовать замораживание/размораживание, поскольку блокировка/разблокировка существует в контексте программирования многопоточности.

public class FreezeableValue<T>  
{  
 private bool frozen;  
 private T value;

 public FreezeableValue()
 {
    frozen = false;
 }

 public FreezeableValue(T value)
 {
    this.value = value;
    frozen = false;
 }

 public void Freeze(bool frozen)
 {
    this.frozen = frozen;
 }

 public T Value
 {
    get { return value; }
    set
    {
        if (!frozen) this.value = value;
    }
 }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню