我正在使用.NET框架,我真的希望能够创建一个我所有网站都使用的自定义类型的页面.当我尝试从控件访问页面时出现问题.我希望能够返回我的特定类型的页面而不是默认页面.有没有办法做到这一点?
public class MyPage : Page
{
// My own logic
}
public class MyControl : Control
{
public MyPage Page { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 150
听起来你想要的是返回类型协方差.C#不支持返回类型协方差.
返回类型协方差是覆盖基类方法的地方,该方法返回一个不太具体的类型,返回更具体的类型:
abstract class Enclosure
{
public abstract Animal Contents();
}
class Aquarium : Enclosure
{
public override Fish Contents() { ... }
}
Run Code Online (Sandbox Code Playgroud)
这是安全的,因为通过Enclosure的内容的消费者期望动物,并且水族馆承诺不仅满足该要求,而且,做出更严格的承诺:动物总是鱼.
C#不支持这种协方差,并且不太可能支持.CLR不支持它.(它受C++和CLR上的C++/CLI实现支持;它通过生成我在下面建议的类型的魔法辅助方法来实现.)
(有些语言也支持形式参数类型的逆转 - 您可以覆盖一个方法,该方法使用带有Animal的方法获取Fish.同样,合同得到满足;基类要求处理任何Fish,并且派生class承诺不仅处理鱼类,而且处理任何动物.同样,C#和CLR不支持形式参数类型的逆转.)
解决此限制的方法是执行以下操作:
abstract class Enclosure
{
protected abstract Animal GetContents();
public Animal Contents() { return this.GetContents(); }
}
class Aquarium : Enclosure
{
protected override Animal GetContents() { return this.Contents(); }
public new Fish Contents() { ... }
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以获得覆盖虚拟方法的好处,并在使用编译时类型Aquarium时获得更强的输入.
通过接口,我通过显式实现接口来解决它:
public interface IFoo {
IBar Bar { get; }
}
public class Foo : IFoo {
Bar Bar { get; set; }
IBar IFoo.Bar => Bar;
}
Run Code Online (Sandbox Code Playgroud)