【问题标题】:How may I return a const reference to an object from a method? [duplicate]如何从方法返回对对象的 const 引用? [复制]
【发布时间】:2018-05-24 17:22:43
【问题描述】:
public Item getItem(ulong itemId)
{
    Item item = items[itemId]
    return item;
}

现在的问题是:getItem 的被调用者必须能够检索到item 持有的信息;但不要修改它。

抱歉,但我比 C# 更了解 C++...恐怕我必须暂时退回到 C++,以便让自己清楚我想要实现的目标...所以这就是我在这种情况下会用 C++ 做:

const Item& getItem(unsigned long itemId)
{
    const Item& item = items[itemId];
    return item;
}

很好 - 现在调用 getItem 的人可以调用 item 上的 getter,但不能调用 setter。

我需要在 C# 中实现类似的结果...有可能吗?

【问题讨论】:

  • 这取决于Itemclass 还是struct
  • 虽然您可以一起破解某些东西,但 C# 通常不以这种方式使用。有什么阻止您更改Item 以使属性只读?
  • @RonBeyer 或返回 Item 实现的接口,该接口仅公开 getter
  • 为了完整性(以防万一还不清楚):C# 没有 C++ 的“const 正确性”的概念(就此而言,大多数其他语言也没有)。结构的不变性有一些支持,但由于不变性不是结构的目的(并且使用它们还有其他后果),这不是通常的方法。如果您的代码库确实需要阻止调用者做坏事,那么包装接口或类是可行的方法,正如其他人所提到的,但在许多情况下 C++ 将使用const,C# 代码库将只是去“不要那样做,那么”。

标签: c# constants return-value


【解决方案1】:

您可以使用接口仅显示 getter,同时在实现该接口的类中仍支持 setter。只要您返回 interface,任何消费者都将被限制为仅使用该接口定义的 getter。

public interface IItem {
    string SomeProperty { get; }
}

public class Item : IItem {
    public string SomeProperty { get; set; }
}

public class ItemHandler {
    private Item _item = new Item();

    public IItem getItem() {
        _item.SomeProperty = "A Value";
        return _item;
    }
}

class Program {
    static void Main(string[] args) {
        var itemHandler = new ItemHandler();
        var item = itemHandler.getItem();

        // You can read the property
        Console.WriteLine(item.SomeProperty);

        // You can't write to the property
        //item.SomeProperty = "A New Value";
    }
}

【讨论】:

  • 哇——太酷了!!!
  • 当然,客户端总是可以转换成原始对象并访问setter。 ( item as Item).SomeProperty = "Cheating"; 完全合法,不会抛出错误。我认为 OP 需要通过设计强制执行不变性。
  • 一般来说,你只做这样的事情来保护开发者不被意外踩到数据。为了使其真正不可变,事情变得更加复杂。这归结为您是否试图指导开发人员或强制执行约束。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 2021-01-30
相关资源
最近更新 更多