【问题标题】:C# Covariant Returns for Auto-Implemented Properties自动实现属性的 C# 协变返回
【发布时间】:2021-06-04 15:12:49
【问题描述】:

如你所知,C# 9.0 (.Net 5) now allows Covariant Returns。我需要帮助将其应用于一组具有自动实现属性的类。

我有两个代表金融银行账户和交易的抽象类。我将它们抽象化,因为我将从各种数据源中提取数据,虽然主要属性将在所有数据源中通用,但每个数据源可能有我想要保留的其他字段。两个类之间存在一对多关系(1 个账户有很多交易,1 个交易只属于 1 个账户)。

public abstract class BankAccount
{
    public string Name { get; set; }
    public IList<Transaction> Transactions { get;  set; } = new List<Transaction>();
    ...
}

public abstract class Transaction
{
    public string Name { get; set; }

    public virtual BankAccount BankAccount { get; set; } // This doesn't work unless I remove set;
    ...
}

这是一个具体实现的例子

public class PlaidBankAccount : BankAccount
{
    public string PlaidId { get; set; }
    ...

}
public class PlaidTransaction : Transaction
{
    public string PlaidId { get; set; }
    public override PlaidBankAccount BankAccount { get; set; } // This doesn't work unless I remove set;
    ...
}

我想要做的是重写基类 getter 和 setter,以便它们使用派生类。例如:

如果我创建具体事务的实例并调用 BankAccount getter,我想获得派生 PlaidBankAccount 的实例而不是基 BankAccount

我发现,当我只在基类中定义虚拟 getter 并在派生类中覆盖它时,它就可以工作。但就像我添加两个属性 {get;set;} 一样,我得到了与以前的 C# 版本相同的错误:

error CS1715: 'PlaidTransaction.BankAccount': type must be 'BankAccount' to match overridden member 'Transaction.BankAccount'

我该如何解决这个问题?

【问题讨论】:

  • 你有什么运气吗?我目前无法使其正常工作。在编译时一切似乎都很好,但在运行时,该对象似乎有两个同名的“银行帐户”对象,并且期望接收​​ plaidbankaccount 的引用在收到 null 时却遇到了 null 引用异常引用属性时的银行帐户对象
  • 我最终定义为 PlaidBankAccount { get { return (PlaidBankAccount)base.BankAccount }}

标签: oop inheritance .net-5 c#-9.0 covariant-return-types


【解决方案1】:

在 C# 9 中,属性只有在 只读 时才能具有协变返回,因此很遗憾,set; 是不可能的。

覆盖属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称。从 C# 9.0 开始,只读覆盖属性支持协变返回类型。被覆盖的属性必须是虚拟的、抽象的或覆盖的。

来自Microsoft Docs - Override keyword

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2011-02-10
    • 2016-01-05
    • 2011-11-26
    • 2010-11-19
    • 2021-04-14
    相关资源
    最近更新 更多