动态铸造C#

Bob*_*der 1 c# casting dynamic

我有父类X和父类H.

H在其字段数据中具有对类型X的引用.H的构造函数需要类型为X的实例,然后将其存储在引用中.

然后我从X派生出一个Child类x1,从H派生出一个子类h1.

h1将在其构造函数中接受X或x1的实例.

但是,在父类X中尚未定义的x1的方法和属性将不可用于h1.

如何在类h1中永久地将x1转换为x1的类型?

Eri*_*ert 8

让我们首先将问题重写为可理解的东西.而不是X和H,我们称之为食物和动物.您的方案是:

abstract class Animal
{
    protected Food favourite;
    protected Animal(Food f) { this.favourite = f; }
}
abstract class Food
{
}
sealed class Banana : Food 
{
    public void Peel() {}
}
sealed class Monkey : Animal
{
    public Monkey(Banana banana) : base(banana) {}
    public PeelMyBanana()
    {
        this.favourite.Peel(); // Error, favourite is of type Food, not Banana
    }
}
Run Code Online (Sandbox Code Playgroud)

你的问题是:

我如何永久地将"最爱"称为"猴子"中的"香蕉"类型?

简短的回答是:你做不到.该字段属于给定类型,可以包含对Food类型实例的任何引用.编译器和运行时不知道或不关心您碰巧知道对事实上将分配给该字段的事物类型的更强限制.

有很多方法可以解决这个问题.您可以添加一个为您进行转换的访问者:

sealed class Monkey : Animal
{
    public Monkey(Banana banana) : base(banana) {}

    private Banana Favourite { get { return (Banana)this.favourite; } }        

    public PeelMyBanana()
    {
        this.Favourite.Peel(); // Works
    }
}
Run Code Online (Sandbox Code Playgroud)

或者您可以对基类进行泛化:

abstract class Animal<F> where F : Food
{
    protected F favourite;
    protected Animal(F f) { this.favourite = f; }
}
abstract class Food
{
}
sealed class Banana : Food 
{
    public void Peel() {}
}
sealed class Monkey : Animal<Banana>
{
    public Monkey(Banana banana) : base(banana) {}
    public PeelMyBanana()
    {
        this.favourite.Peel(); // Legal; Animal<Banana>.favourite is of type Banana
    }
}
Run Code Online (Sandbox Code Playgroud)