gpt4 book ai didi

d - 具体类数组与接口(interface)数组不协变

转载 作者:行者123 更新时间:2023-12-01 10:51:56 25 4
gpt4 key购买 nike

我在为我的 dataaccess.mysqlclient 模块提供抽象基础层时遇到了一个小问题,我在其中定义了一组最低要求的接口(interface)和一组实现它们的类。

现在 dmd 编译器提示:

错误:@property MySqlColumnInfo[]() 类型的函数 dataaccess.mysqlclient.MySqlReader.columns 覆盖但与@property IDbColumnInfo[]() 类型的 dataaccess.dbclient.IDbReader.columns 不协变
退出代码 1

相关代码行如下所示:

IDbReader:

interface IDbReader
{
@property IDbColumnInfo[] columns();
// ...
}

MySqlReader:

class MySqlReader : IDbReader
{
private MySqlColumnInfo[] _columns;
@property public MySqlColumnInfo[] columns() {return _columns;}
// ...
}

有几种方法可以解决这个编译器问题;

  • 将具体属性声明为 IDbColumnInfo[]
  • 将数组包装在列表类中

如果我再考虑一下,可能还会有更多。不过,这些看起来都不是很优雅。

大问题来了:

  • 我是否忽略了一些简单的事情?
  • 实现数组能否与接口(interface)数组协变?

我也无法想象编译器提示的原因。我的代码中有更复杂的结构,它们编译得很好。因此,如果有人可以解释为什么这不能按原样工作,我们将不胜感激。

最佳答案

你遇到了array covariance的问题.

让我们假设您的代码编译正常。现在,考虑以下代码:

class SomeOtherColumnInfo : IDbColumnInfo {}

IDbReader reader = new MySqlReader(...);
IDbColumnInfo[] columns = reader.columns;
columns[3] = new SomeOtherColumnInfo(); // OK

由于数组是可变的,我们可以用其他 IDbColumnInfo 派生类的实例覆盖它的元素。问题是我们还修改了 MySqlReader 的私有(private) _columns 字段。所以,现在我们有一个 SomeOtherColumnInfo 实例作为 MySqlColumnInfo[] 数组的成员。因此,我们在没有使用强制转换或其他不安全代码的情况下破坏了类型系统。由于编译器会意外地阻止我们这样做,它会拒绝将类的可变数组隐式转换为其他类的数组,即使这些类是相关的。

现在,我认为如果返回的数组不是可变的(即 const 或不可变的),D 允许编译是有意义的。但是,编译器也不喜欢那样。我不知道这是否是一个遗漏,或者是否有我不知道的原因。

关于d - 具体类数组与接口(interface)数组不协变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18158106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com