【问题标题】:Passing a byte[] around传递一个字节[]
【发布时间】:2011-09-11 00:28:39
【问题描述】:

我们使用的第三方生成代理将 BLOB 数据类型暴露为 byte[],然后我们通过代码生成暴露该值,如下所示:

public byte[] FileRawData
{
    get { return internalDataRow.FileRawData; }
    set { this.internalDataRow.FileRawData = value; }
}

然后在整个应用程序中使用此属性(可能在不同的程序集中)。根据 FxCop 规则,属性不应暴露数组。那么,这里有什么更好(或最好)的方法?在这种情况下,其他人会怎么做?

  1. 切换到这些类型的方法。
  2. 更改为集合(即ICollection<T>IList<T> 实现)
  3. 关闭此 FxCop 规则。

选项 3 始终是可能的,但如果我们应该以不同的方式做事,那么我更愿意这样做。

【问题讨论】:

  • 不,fxcop 实际上是在警告您其他事情。返回数组的深拷贝 效率非常低。返回一个reference 来查看你真正在做什么是不够聪明的。更糟糕的是,任何客户端代码都可以在您不知情的情况下更改数组。你最好把这个类设为internal
  • 访问该属性的代码是否有任何理由不应修改数组?
  • Hans:将其设为内部不是一种选择,因为这发生在一个通用程序集中,我们系统的其他部分可以访问该程序集。我是否认为我应该返回 ReadOnlyCollection<T> 或类似名称? internalDataRow 的实现也只是传回了对其数组的引用,所以返回除此之外的任何内容都不会效率低下吗?
  • @Daniel:是的,如果您的 API 的客户端不会修改数组,ReadOnlyCollection<T> 将是理想的选择。

标签: c# collections fxcop


【解决方案1】:

这种情况下的常见问题是不可变性。当 byte[] 返回时,调用者可以更改它,而无需通过您的设置器。想想如果有人这样做会发生什么

byte[] retVal = MyInstance.FileRawData;
retVal[1] = 0x00;

可能根本不是您想要的,因为 MyInstance 内部的值已更改,这可能会导致问题。因此,为了阻止您克隆数组,但这可能会长时间运行,并且属性不应用于长时间运行的操作。解决它的最佳方法是切换到集合和获取方法,除非数组总是很小。当然当你开始写 GetFileRawData() 作为方法名时,FXCop 会提示你它应该是一个属性,你赢不了 grin 在这种情况下,只需在代码中禁用它即可;对于那一种方法。

【讨论】:

  • 但是如果我将数组公开为List<T>Collection<T>,也会出现同样的问题,不是吗?来电者可以做myInstance.FileRawData.Delete(index)?解决这个问题的唯一方法是公开ReadOnlyCollection<T>
  • 好吧,为了创建一个列表,它将执行一个复制。因此,如果您要返回从字节数组创建的列表或集合,而不是仅在内部将列表替换为字节,那会很好(但 ReadOnly 会更有意义)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多