【问题标题】:Return reference to list element to be able to assign a value to it返回对列表元素的引用以便能够为其赋值
【发布时间】:2018-06-04 10:52:08
【问题描述】:

我来自 C++ 背景,这里有一个简单的问题。作为班级成员,我有以下列表:

public enum FieldColor {Empty, Blue, White};
private List<List<FieldColor>> m_board = new List<List<FieldColor>>();

现在我有这么简单的方法:

private FieldColor GetFieldColor(GridCoordinates coordinates) {
    return m_board[coordinates.row][coordinates.column];
}

现在我想用这个方法给coordinate赋值,我写了这个:

    GetFieldColor(coordinates) = color;

我得到这个错误:

赋值的左边必须是变量、属性或 索引器 [Assembly-CSharp]

有什么解决办法。

【问题讨论】:

    标签: c#


    【解决方案1】:

    你总是可以使用Ref return

    从 C# 7.0 开始,C# 支持引用返回值(ref 返回)。引用返回值允许方法返回一个 引用一个变量,而不是一个值,返回给调用者。这 然后,调用者可以选择将返回的变量视为 通过值或引用返回。调用者可以创建一个新的 本身是对返回值的引用的变量,称为 参考本地。

    限制

    方法可以返回的表达式有一些限制 作为参考返回值。限制包括:

    • 返回值的生命周期必须超出方法的执行范围。换句话说,它不能是局部变量 在返回它的方法中。它可以是实例或静态字段 一个类,或者它可以是传递给方法的参数。尝试 返回局部变量会生成编译器错误 CS8168,“Cannot 通过引用返回本地 'obj',因为它不是本地 ref。”

    • 返回值不能是文字空值。返回 null 会生成编译器错误 CS8156, "An expression cannot be used in this 上下文,因为它可能不会通过引用返回。”

    • 具有 ref 返回的方法可以将别名返回给当前值为空(未实例化)值或可为空类型的变量 对于值类型。

    • 返回值不能是常量、枚举成员、属性的按值返回值、类的方法或 结构。违反此规则会生成编译器错误 CS8156,“An 表达式不能在这种情况下使用,因为它可能不是 通过引用返回。”

    示例

    private ref int GetFieldColor(GridCoordinates coordinates)
    {
        return ref m_board[coordinates.row][coordinates.column];
    }
    

    有效用法

    GetFieldColor(gridCoordinates) = 345;
    

    或者您可以使用indexer

    索引器允许类或结构的实例被索引,就像 数组。无需显式设置或检索索引值 指定类型或实例成员。索引器类似于属性 除了它们的访问器带参数。

    public int this[GridCoordinates coordinates]
    {
       get => m_board[coordinates.row][coordinates.column];
       set => m_board[coordinates.row][coordinates.column] = value;
    }
    

    用法

    this[GridCoordinates] = 345
    

    【讨论】:

      【解决方案2】:

      你需要为相同的创建一个单独的setter方法

      private FieldColor SetFieldColor(GridCoordinates coordinates, FieldColor color) {
          m_board[coordinates.row][coordinates.column] = color;
      }
      

      【讨论】:

      • 这个怎么样? var correspondingBoardCell = GetFieldColor(coordinates); correspondingBoardCell = color;
      • @Narek 那行不通,因为您正在修改引用 correspondingBoardCell 而不是引用的对象
      【解决方案3】:

      您还可以重载[] 运算符来满足您的需求。我发现这种方法比 ref return 不那么老套,而且在 C# 哲学中更多。

      public FieldColor this[int row, int column]
      {
          get => m_board[row][column];
          set => m_board[row][column] = value;
      }
      

      如果需要,使用前一个重载的第二个重载:

      public FieldColor this[GridCoordinates coordinates]
      {
          get => this[coordinates.row, coordinates.column];
          set => this[coordinates.row, coordinates.column] = value;
      }
      

      用法:

      field[0, 1] = FieldColor.Empty;
      var color = field[0, 1];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-11
        • 2020-12-01
        • 2020-09-20
        • 2017-05-03
        • 1970-01-01
        • 2016-08-06
        • 1970-01-01
        • 2020-12-09
        相关资源
        最近更新 更多