作者:nashiyizhiyu_847_695 | 来源:互联网 | 2022-12-10 07:18
鉴于这些接口和类......
public interface IPage
{
string PageTitle { get; set; }
string PageContent { get; set; }
}
public abstract class Page
: IPage
{
public string PageTitle { get; set; }
public string PageContent { get; set; }
}
public class AboutPage
: Page
, IPage
{
}
public interface IPageAdminViewModel
where T : IPage
{
IEnumerable Pages { get; }
}
public abstract class PageAdminViewModel
: IPageAdminViewModel
where T: IPage
{
public IEnumerable Pages { get; set; }
}
为什么使用IPage
作为接口类型参数不编译....
public class AboutPageAdminViewModel
: PageAdminViewModel
, IPageAdminViewModel // ERROR HERE - I realise this declaration is not required, just indicating where the error is (not)
{
}
'AboutPageAdminViewModel'未实现接口成员'IPageAdminViewModel .Pages'.'PageAdminViewModel .Pages'无法实现'IPageAdminViewModel .Pages',因为它没有匹配的返回类型'IEnumerable '.
....使用具体课时AboutPage
呢?
public class AboutPageAdminViewModel
: PageAdminViewModel
, IPageAdminViewModel // NO ERROR - I realise this declaration is not required, just indicating where the error is (not)
{
}
从本质上讲,我不明白为什么返回类型与返回类型IEnumerable
不匹配IEnumerable
.
我想创建一个IPageAdminViewModel
以参数为例的方法.我想知道如何/如果我能够AboutPageAdminViewModel
符合这个要求.
1> Eric Lippert..:
从本质上讲,我不明白为什么返回类型与返回类型IEnumerable
不匹配IEnumerable
.
首先:您是正确的,财产符合IEnumerable
合同的所有要求.允许这样做对C#来说是类型安全的.
您想要的功能称为虚拟返回类型协方差,C#不支持它.您可以通过比您更简单的示例看到这一点:
class Animal {}
class Tiger : Animal {}
interface ICage { Animal GetAnimal(); }
class TigerCage : ICage { public Tiger GetAnimal() => new Tiger(); }
这是完全安全的. ICage
要求实施者有一个返回动物的方法,并且TigerCage
; 它返回一个Tiger
是Animal
.这是安全的,但不合法.
C++具有此功能.C#没有.
人们一直在要求这个功能15年以上; 你可以在这个网站上搜索"C#return type covariance",你会发现很多答案(由我和其他人).
它从未被实现,因为CLR本身不支持它,使用显式接口实现和阴影有简单的解决方法,并且它将新的脆弱基类故障引入生态系统.由于这些原因和其他原因,与其他更有价值的功能相比,编译器团队一直是低优先级.
如果你想要它,请在GitHub论坛上提倡它; 我相信你会有合作,但我也不会屏息等待编译团队实施它; 我们已经等了很久了!
顺便说一句,没有人要求虚拟参数类型的逆转 - 也就是说,覆盖一个方法,该方法将Tiger带有一个带动物的方法.但它同样安全.