如你所知,c# 9.0 (Net 5)现在允许协变收益。我需要帮助将此应用于一组具有自动实现属性的类。
我有两个抽象类表示金融银行账户和交易。我之所以将它们抽象,是因为我将从各种数据源中提取数据,而主要属性在所有数据源中都是通用的,每个数据源可能都有我想要保留的其他字段。这两个类之间存在一个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'
我该如何解决这个问题?
在c# 9中,属性只有在只读时才能够有协变返回。,所以不幸的是,没有set;
是可能的。
重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称。从c# 9.0开始,只读重写属性支持协变返回类型。被覆盖的属性必须是虚拟的、抽象的或覆盖的。
From Microsoft Docs - Override关键字