С#, Скопировать один bool в другой (по ref, not val)

Я на кирпичной стене здесь. Можно ли скопировать один bool в ref другого. Рассмотрим этот код.,.

bool a = false;
bool b = a;

b теперь является полностью отдельным bool со значением false. Если впоследствии я изменю a, это не повлияет на b. Можно ли сделать a = b по ref? Как мне это сделать?

Большое спасибо

Ответ 1

Нет. Поскольку bool является типом значения, он всегда будет скопирован по значению.

Лучший вариант - обернуть ваш bool в класс - это даст ему семантику ссылочного типа:

public class BoolWrapper
{
     public bool Value { get; set; }
     public BoolWrapper (bool value) { this.Value = value; }
}

BoolWrapper a = new BoolWrapper(false);
BoolWrapper b = a;
b.Value = true; 
 // a.Value == true 

Ответ 2

Спасибо @Reed за его ответ (+1)! Он подтолкнул меня к более "родовому" решению!:)

public class ValueWrapper<T> where T : struct
{
    public T Value { get; set; }
    public ValueWrapper(T value) { this.Value = value; }
}

Ответ 3

Маленькое расширение на ответ Андрея... это позволяет вам назначить его любому типу, который вы хотите в конце. Итак:

        ValueWrapper<bool> wrappedBool = new ValueWrapper<bool>(true);

        bool unwrapped = wrappedBool;  // you can assign it direclty:

        if (wrappedBool) { // or use it how you'd use a bool directly
            // ...
        }

public class ValueWrapper<T>
{

    public T Value { get; set; }

    public ValueWrapper() { }

    public ValueWrapper(T value) { 
        this.Value = value; 
    }

    public static implicit operator T(ValueWrapper<T> wrapper)
    {
        if (wrapper == null) {
            return default(T);
        }
        return wrapper.Value;
    }

}

код >

Ответ 4

это может быть не то, что вы хотите, но если ваш сценарий таков, что вы хотите функцию, которую вы вызывали, чтобы изменить локальное логическое значение, вы можете использовать ref или out keyworkd.

bool a = false;

F(ref a);
// a now equals true

...

void F(ref bool x)
{
x = true;
}

Ответ 5

Bool - тип значения и не может быть скопирован по ссылке.

Ответ 6

Итак, я предполагаю, что вам нужно передать ссылку bool, которую вы не можете обернуть классом BoolWrapper, потому что bool живет в каком-то месте, которое вы не можете или не хотите изменять.

Это можно сделать!

Сначала объявите, что будет выглядеть любая ссылка bool

/// <summary> A reference to a bool.</summary>
/// <param name="value">new value</param>
/// <returns>Value of boolean</returns>
public delegate bool BoolRef(bool? value = null);

Теперь вы можете сделать ссылку на myBool следующим образом

    bool myBool; // A given bool that you cannot wrap or change
    private bool myBoolRef(bool? value) {
        if (value != null) {
            myBool = (bool)value;
        }
        return myBool;
    }

И используйте его следующим образом:

    void myTestCaller() {
        foo(myBoolRef);
    }
    void foo(BoolRef b) {
        bool c = b(); // get myBool
        b(true); // set myBool to true
    }

Тот же трюк работает для других типов значений, таких как int

Ответ 7

У меня был случай, когда я хотел, чтобы один класс менял другой класс "bool" - обратите внимание, что есть способы справиться с этой ситуацией, но это доказательство концепции с помощью Actions.

public class Class1 
{
    bool myBool { get; set; }
    void changeBoolFunc(bool val) { myBool = val; }
    public Class1() 
    {
        Action<bool> changeBoolAction = changeBoolFunc;
        myBool = true; 
        Console.WriteLine(myBool);    // outputs "True"
        Class2 c2 = new Class2(changeBoolAction);
        Console.WriteLine(myBool);    // outputs "False"
    }
}
public class Class2
{
    public Class2(Action<bool> boolChanger) { boolChanger(false); }
}
void Main()
{
    Class1 c1 = new Class1();
}

Ответ 8

Просто используйте флаги как Nullable<bool> или bool? и установите те в структуре, которые переданы в общий метод. Класс ValueWrapper<T>, приведенный выше, по существу является тем, что делает Nullable<T>.