繁体   English   中英

C# 通用 inheritance,底座 class 铸造

[英]C# generic inheritance, base class casting

我想制作包含 generics 的以下 inheritance,但最终将a as A<XBase>始终导致 null,因为转换无效。 任何人都可以详细说明为什么这个转换无效,以及这个问题的解决方案。

public class XBase {}
public interface A<T> where T : XBase 
{
    //Edited
    void Method(T param);
}


public class Implementor : A<Implementor.ImplementorX > 
{
    public class ImplementorX : XBase {public int a;}

    //Edited
    void Method(ImplementorX param) {}
}

public class HelloWorld
{
    public static void Main(string[] args)
    {
        var a = new Implementor();
        
        var castRes = a as A<XBase>;
        Console.WriteLine(castRes != null);
    }
}

参见实例https://rextester.com/BTNVT61833

编辑:添加了一个方法来interface A<T> bc 否则它可以通过 @DavidG 的响应来解决

如果您进行显式转换:

var castRes = A<XBase>(a);

然后你会看到以下错误:

无法将类型为“”的 object 转换为类型“`

为什么? 在我看来,最好使用真实世界的例子来理解。 根据这个解释重命名了类。 有一些评论将解释映射到您所讨论的课程。

抽象:

// XBase 
public class Animal { }

// class ImplementorX : XBase {public int a;}
public class Bird : Animal
{
    public string WingColor { get; set; }
}

// interface A<T> where T : XBase 
public interface IHat<T> where T : Animal
{
    void Hide(T param);

    T Pull();
}

具体实现:

// class Implementor : A<Implementor.ImplementorX > 
public class Peacock : IHat<Bird>
{
    // void Method(ImplementorX param) {}
    void IHat<Bird>.Hide(Bird param)
    { }

    public Bird Pull()
    { }
}

以及如何称呼它:

public static void Main(string[] args)
{
    Peacock peacockHat = new Peacock();

    IHat<Animal> animalHat = (IHat<Animal>) peacockHat; // runtime error 'Unable to cast
    // object of type 'HelloWorld.Peacock' to type 'HelloWorld.IHat`1

    // because 
    animalHat.Hide(new Dolphin()); // Hide a dolphin in a peacock hat?  
}

所以我们不能向Dolphin hide Peacock的帽子。 这不好。 CLR 防止我们做出不恰当的行为。

简而言之:

简而言之,假设您有两只动物,例如WolfSheep 这些类实现了 IAnimal 接口:

public interface IAnimal
{    }

public class Wolf: IAnimal
{    }

public class Sheep : IAnimal
{    }

所以SheepWolf类实现了继承的接口IAnimal

            IAnimal
             /  \
            /    \
         Sheep   Wolf 

然后这些动物就可以关在笼子里了:

public class Cage<T> where T : IAnimal
{
    public void Put(T animal)
    {   }
}

然后为Sheep创建一个笼子。 之后有人想将Sheep cage 投射到IAnimal

Cage<Sheep> sheepCage = new Cage<Sheep>();
sheepCage.Put(new Sheep());

Cage<IAnimal> animalCage = (Cage<Wolf>)sheepCage; // compile error
// if there were no error, then you will be able to do:
animalCage.Put(new Wolf()); // it is not good idea

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM