【问题标题】:Assign value of a reference property to a variable将引用属性的值分配给变量
【发布时间】:2021-01-06 21:21:49
【问题描述】:

我有一个场景,我想将值类型bool(标有ref 的值类型)的引用传递给另一个类的构造函数,并想在另一个类中更新它的值。像这样的东西。有没有办法保存变量的引用。 (我用public标记了东西,我知道公共变量可以从任何地方访问)

public class A
{
    public bool Update;
    public void DoSomething()
    {
        B b = new B(ref Update);
    }
}

public class B
{
    private ref bool _val; //Is it possible to create a variable like this. If not is there a way to achieve what I am doing.
    public B(ref bool value)
    {
        _val = value;
    }
    private void UpdateValue()
    {
        _val = true;
    }
}

【问题讨论】:

  • 我不清楚您要做什么。当 B 类中的字段 _val 更改时,您是否希望更改 A 类中的字段 Update 的值?
  • 您不能在类中存储ref。但我一直想要的是boxed bool。这里的解决方案是传递一个包含布尔值的对象或一个可以就地更改它的委托。

标签: c# ref value-type


【解决方案1】:

用引用类型包装值

public class CanUpdate
{
    public bool Value { get; set; }
}

然后

public class B
{
    private readonly CanUpdate _canUpdate;

    public B(CanUpdate value)
    {
        _canUpdate = value;
    }

    private void UpdateValue()
    {
        _canUpdate.Value = true;
    }
}

A 类将“看到”B 类更改的值

public class A
{
    private CanUpdate CanUpdate;

    public A()
    {
        CanUpdate = new CanUpdate { Value = false };
    }

    public void DoSomething()
    {
        Console.WriteLine(CanUpdate.Value); // false

        var b = new B(CanUpdate);
        b.UpdateValue();

        Console.WriteLine(CanUpdate.Value); // true
    }
}

为值拥有自己的专用类型可提高可读性并使代码对其他人更易于理解。

【讨论】:

    【解决方案2】:

    如果您只需要一次该值,则只需拥有一次。从一个类到另一个类,从 A 到 B,反之亦然。

    public class A
    {
        B b = new B(false);
        public bool Update { 
            get { return b.BooleanValue; }
        }
    
        public void DoSomething()
        {
    
        }
    }
    
    public class B
    {
        public B(bool value)
        {
            _val = value;
        }
        private void UpdateValue()
        {
            _val = true;
        }
    
        public bool BooleanValue{ 
            get { return _val; }
        }
    }
    

    如果B的使用真的像临时一样

    public void DoSomething()
    {
        B b = new B(ref Update);
    }
    

    然后让B的一个方法B返回布尔值。

    【讨论】:

      【解决方案3】:

      将字段设置为引用类型 (private ref bool _val;) 是没有意义的,因为它只是一个类作用域变量。属性设置器不允许您将 ref 修饰符添加到自动 value 参数,因此这也不起作用。此外,您不能将属性作为ref 参数传递(即obj1.Method(ref obj2.Value) 不起作用)。

      我认为您要描述的是observer pattern,观察者在其中观察主题状态的变化并做出反应。它类似于 JavaScript 中的事件监听器,但不是观察 actions,而是观察 state。一个简单的实现可能如下所示:

      public class Subject
      {
          private readonly Observer[] Observers;
          private string _val;
          public string Val
          {
              get => _val;
              set
              {
                  // Update every observer's value when this is set.
                  foreach (Observer o in Observers)
                  {
                      o.Val = value;
                  }
                  _val = value;
              }
          }
          public Subject(params Observer[] observers)
          {
              Observers = observers;
          }
      }
      
      public class Observer
      {
          public string Val { get; set; }
      }
      
      // In execution:
      var o1 = new Observer();
      var o2 = new Observer();
      var subject = new Subject(o1, o2);
      subject.Val = "hello there";
      Console.WriteLine("o1: " + o1.Val);
      Console.WriteLine("o2: " + o2.Val);
      Console.WriteLine("subject: " + subject.Val);
      
      // Output:
      // o1: hello there
      // o2: hello there
      // subject: hello there
      

      请注意,这种特殊情况有一些限制,因为该关系仅适用于从 Subscriber 到 Observer(即,如果您直接更改观察者的 Val,它不会被其他观察者反映并进一步更新为Subject 将覆盖对 Observer 的任何更改)。

      【讨论】:

      • 我不会说“将字段设置为 ref 没有意义”,这只是 ECMA-335 标准不允许的,因为它可能会泄漏指向堆的堆栈指针。 C++ 一直使用它,但它对于托管指针是不安全的。
      • 我有 WPF 应用程序,我只需要更新一个布尔属性,该属性绑定到子类的进度条。所以我不想将整个对象作为 B b=new B(this) 传递,我只是想看看是否有办法在子类中的操作执行时传递 ref 参数。我也不想引发事件。我知道观察者模式。感谢您的帮助。
      猜你喜欢
      • 2012-04-09
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      • 2016-12-24
      • 2021-09-20
      • 2023-03-04
      相关资源
      最近更新 更多