【问题标题】:how to pass a list cell by ref?如何通过 ref 传递列表单元格?
【发布时间】:2015-07-13 17:16:14
【问题描述】:

情况:

我有一个List<DataGridView> temp。我需要通过引用将特定索引传递给函数,因为我遍历它们并且需要更改受影响的索引。以下是我尝试/使用的方法

方法一

functionA(ref temp[0]);
A property, indexeur or access to a dynamic member cannot be passed as ref or out (free traduction)

不过我能做到:

方法二

DataGridView bobu = temp[0];
functionA(ref bobu );

还有这项工作。有没有办法使用我的方法 1 而不是使用像 方法 2 中的技巧?

【问题讨论】:

  • 我不认为 1 和 2 是等价的。在方法 1 中,您尝试引用 temp[0],这将允许您在列表的“插槽”0 中重新分配“DataGridView”。但是,方法 2 允许您在 bobu 上执行相同操作,如果您在 functionA 中重新分配它,它对 temp[0] 没有影响
  • @FrankJ 但是更改bobu 的属性更改temp[0],因为DataGridView 是一个类,而不是一个结构。我不明白为什么ref 甚至在这里,因为DataGridView 已经是一个引用类型。
  • 到底发生了什么!但是有没有办法不需要卫生棉条变量?对变量名感到抱歉,下次会使用更好的!
  • 您可以更改DataGridView 的内容,如果这就是您想要的,您根本不需要引用,因为它是一个引用类型。只有当您想在functionA 中将DataGridView 的新实例new 分配给传入的变量并希望查看函数外部的更改时,才需要它。如果你了解 C++,这个概念类似于双指针。
  • this from MSDN如何使用ref

标签: c#


【解决方案1】:

之前也曾多次询问过类似的问题,以下链接应该会有所帮助:

What is the use of "ref" for reference-type variables in C#?

idea 的 ref 或 out 关键字就像对引用的引用,就像指向指针的指针,所以它们可以一起用来改变对不同分配的引用。通常情况下,它会按值传递引用,因此即使字段和属性的值可以更改,但原始内存引用不能更改。

我们不能对属性 indexer 使用 ref 关键字,因为它无法确定它们是否实现了 setter 或其只读,因此您需要复制到变量,就像您所做的那样,没有这样的问题,是否可写,请查看以下讨论:

C# property and ref parameter, why no sugar?

正如已经建议在 DataGridView 中更改值,您可以传递简单类型,它可以修改对象可访问的属性/字段

【讨论】:

    【解决方案2】:

    根据您的 cmets,听起来您只想更改列表中项目的 属性,而不是更改列表以引用不同的项目。在这种情况下,ref 不是必需的,因为 DataGridView 是引用类型 - 这意味着当您将变量传递给函数时,您实际上是将 reference 传递给对象(即 与“通过引用”相同)。

    只要把ref从方法签名和调用语法中去掉就可以了。

    如果您确实想要更改列表中的对象,那么您需要将列表传递给方法和一些方法来识别您要更新的哪个对象(例如索引):

    public void functionA(List<DataGridView> list, int index)
    {
        list[index] = {some new object}
    }
    

    请注意,在这种情况下也不需要ref,因为List&lt;T&gt; 也是一个引用类型。

    【讨论】:

      【解决方案3】:

      为此,我实现了一个 Generic Wrapper 来保存引用,其中引用可以通过以下两种方式之一进行初始化,传递对象本身或列表和索引,并具有getter 和 setter

      public class Ref<T>
      {
          private T _ref;
          private IList<T> list;
          private int index;
      
          public Ref(T _ref)
          {
              this._ref = _ref;
          }
      
          public Ref(IList<T> list, int index)
          {
              this.list = list;
              this.index = index;
          }
      
          public void set(T _ref)
          {
              if (this._ref == null)
              {
                  this.list[index] = _ref;
              }
              else
              {
                  this._ref = _ref;
              }
          }
      
          public T get()
          {
              if (this._ref == null)
              {
                  return this.list[index];
              }
              else
              {
                  return this._ref;
              }
          }
      
      }
      

      不要通过引用传递,而是传递所需类型的Ref

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-24
        • 2011-01-28
        • 1970-01-01
        • 1970-01-01
        • 2011-02-03
        • 1970-01-01
        • 2010-10-09
        • 1970-01-01
        相关资源
        最近更新 更多