C#接口基本用法
我有基本接口:C#接口基本用法,c#,oop,interface,C#,Oop,Interface,我有基本接口: public interface IDebtBase { // with properties } 它由另一个接口继承 public interface IDebt : IDebtBase { // with properties } 另一个接口在列表中定义IDebt接口: public interface ILoanBase { List<IDebtBase> Debts { get; set; } } Loan对象实现ILoan: publ
public interface IDebtBase
{
// with properties
}
它由另一个接口继承
public interface IDebt : IDebtBase
{
// with properties
}
另一个接口在列表中定义IDebt接口:
public interface ILoanBase
{
List<IDebtBase> Debts { get; set; }
}
Loan对象实现ILoan:
public class Loan : ILoan
{
List<IDebt> Debts { get; set; }
}
我收到一个错误,指出Loan中的列表需要是IDebtBase而不是IDebt:
“Loan”未实现接口成员“ILoanBase.deborts”
这是可行的,还是接口继承不可行?使用系统;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Loan l = new Loan();
var a = 1;
}
}
public interface IDebtBase
{
// with properties
}
public interface IDebt : IDebtBase
{
// with properties
}
public interface ILoanBase<T> where T : IDebtBase
{
List<T> Debts { get; set; }
}
public interface ILoan : ILoanBase<IDebt>
{
// with properties
}
public class Loan : ILoan
{
public List<IDebt> Debts { get; set; }
}
}
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间控制台应用程序2
{
班级计划
{
静态void Main(字符串[]参数)
{
贷款l=新贷款();
var a=1;
}
}
公共接口IDebtBase
{
//具有属性
}
公共接口IDebt:IDebtBase
{
//具有属性
}
公共接口ILoanBase,其中T:IDebtBase
{
列表{get;set;}
}
公共接口ILoan:ILoanBase
{
//具有属性
}
公共类贷款:伊隆
{
公共列表{get;set;}
}
}
我认为您试图做的是声明一个接口列表,但实际上实现了一个具体类型列表。这对于像C.
这样的静态语言来说是很棘手的。最好的选择是对loan base接口使用泛型
public interface IDebtBase
{
decimal Amount { get; set; }
}
public interface IDebt : IDebtBase
{
int ID { get; set; }
}
public interface ILoanBase<TDebt> where TDebt : IDebtBase
{
List<TDebt> Debts { get; set; }
}
public interface ILoan : ILoanBase<IDebt>
{
decimal Rate { get; set; }
}
public class Debt : IDebt
{
public int ID { get; set; }
public decimal Amount { get; set; }
}
public class Loan : ILoan
{
public static decimal DefaultRate=0.18m;
public Loan()
{
this.Debts=new List<IDebt>();
this.Rate=DefaultRate;
}
public List<IDebt> Debts { get; set; }
public decimal Rate { get; set; }
public void AddDebt(int id, decimal amount)
{
Debts.Add(new Debt() { ID=id, Amount=amount });
}
}
class Program
{
static void Main(string[] args)
{
var loan=new Loan() { Rate=0.22m };
loan.AddDebt(1002, 5400m);
}
}
现在您已将所有贷款收集到一个集合中
static void Main(string[] args)
{
List<ILoanBase> loans=new List<ILoanBase>();
//populate list
var abc=new Loan() { Issuer="ABC", Rate=0.22m };
abc.AddDebt(1002, 5400m);
loans.Add(abc);
//iterate list
foreach (var loan in loans)
{
Console.WriteLine(loan.Issuer);
foreach (var debt in loan.GetDebts())
{
Console.WriteLine(debt.Amount.ToString("C"));
}
}
// ABC
// $5,400.00
}
static void Main(字符串[]args)
{
列表贷款=新列表();
//填充列表
var abc=new Loan(){Issuer=“abc”,利率=22万};
abc.新增债务(10.025亿美元);
新增贷款(abc);
//迭代列表
foreach(贷款中的var贷款)
{
Console.WriteLine(贷款发行人);
foreach(贷款中的var债务。GetDebts())
{
控制台。写线(债务。金额。ToString(“C”));
}
}
//ABC
// $5,400.00
}
让我解释一下为什么这行不通
假设我添加了另一个类Foo:IDebtBase
,然后执行
myLoan.Debts.Add(New Foo());
添加Foo
可用于列表(即,它可用于ILoanBase.deberts
),但不可用于列表(即,它不可用于Loan.deberts
)
因此,如果编译器允许您以您建议的方式在Loan
中实现ILoanBase
,则将违反。使用泛型和泛型约束我将把泛型约束放在哪里,作为ILoan上列表的覆盖?List
和List
是不同的类型。由于IDebt继承了IDebtBase,列表债务不应该在Loan类中工作吗?不,它不工作。查找C#中的协方差和逆变换以了解一些示例。另外,请展示具体的Debt
类实现IDebt
。有趣的是,我会尝试一下。我担心的是我使用的是实体框架,我会混淆它。不,它应该能够处理泛型(毕竟IList是一个基于泛型的对象….IList),这很有意义,谢谢你们把它和Liskov替换原理联系起来。有趣的方法是,你们用“一旦你们开始涉及到集合,用接口构建一个层次结构树是非常棘手的。”这个方法很有意思。我将用我的应用程序来测试这个方法。
public interface ILoan : ILoanBase<Debt> // change from ILoanBase<IDebt>
{
decimal Rate { get; set; }
}
public class Loan : ILoan
{
public static decimal DefaultRate=0.18m;
public Loan()
{
this.Debts=new List<Debt>(); // change from List<IDebt>
this.Rate=DefaultRate;
}
public List<Debt> Debts { get; set; } // Change from List<IDebt>
public decimal Rate { get; set; }
public void AddDebt(int id, decimal amount)
{
Debts.Add(new Debt() { ID=id, Amount=amount });
}
}
public interface ILoanBase
{
string Issuer { get; set; }
IList<IDebtBase> GetDebts();
}
public interface ILoanBase<TDebt> : ILoanBase
where TDebt : IDebtBase
{
List<TDebt> Debts { get; set; }
}
public class Loan : ILoan
{
...
public IList<IDebtBase> GetDebts()
{
return Debts.OfType<IDebtBase>().ToList();
}
}
static void Main(string[] args)
{
List<ILoanBase> loans=new List<ILoanBase>();
//populate list
var abc=new Loan() { Issuer="ABC", Rate=0.22m };
abc.AddDebt(1002, 5400m);
loans.Add(abc);
//iterate list
foreach (var loan in loans)
{
Console.WriteLine(loan.Issuer);
foreach (var debt in loan.GetDebts())
{
Console.WriteLine(debt.Amount.ToString("C"));
}
}
// ABC
// $5,400.00
}
myLoan.Debts.Add(New Foo());