从T到T Base <childbase> </childbase>没有隐式引用转换

时间:2011-12-07 13:55:25

标签: c# .net oop

我有两个不同的类派生自一个基类。它们每个都有一个派生自另一个基类的集合,但派生类不同。

class MasterA : MasterBase<ClientA>
class MasterB : MasterBase<ClientB>

public class MasterBase<ClientClass> where ClientClass : ClientBase
{
    public List<ClientClass> Clients;
} 

Class ClientA : ClientBase
Class ClientB : ClientBase

Class ClientBase

我想要的是一个UserControl,它与两种类型(A或B)的Master / Client的父/子列表一起使用。

public class Test<MasterClass> where MasterClass : MasterBase<ClientBase>
{
    GenericRepository<MasterClass> repo = new GenericRepository<MasterClass>();
    MasterClass master = repo.GetAll;
    // do some changes to (base fields of) the master collection and its client collection !
    repo.SaveOrUpdate(master);
}

但....我无法实例化那个Test类..

var t = new Test<MasterA>();
>> There's no implicit reference conversation from MasterA to MasterBase<ClientBase>

那么,是否有某种方法可以修改Test类以便能够执行我指定的操作?   我真的很感激一些提示。

2 个答案:

答案 0 :(得分:2)

您试图以一种破坏类型安全的方式从更具体的泛型转换为不太具体的泛型。

我改变你的类型代表猫和狗,希望这将证明问题:

void Main()
{

    Test<AnimalList<Animal>> t = new Test<CatList>();
    t.List.Add(new Cat());
    //You just dogged a cat!
    t.List.Add(new Dog());

    //Change your t to something like:
    Test<AnimalList<Animal>> t = new Test<AnimalList<Animal>>();
    t.List.Add(new Cat());
    //You just dogged an *animal* that's perfectly ok!
    t.List.Add(new Dog());
}

public class Test<TAnimalList> where TAnimalList : AnimalList<Animal>
{
    public TAnimalList List { get; set; }
}

public class CatList : AnimalList<Cat> {}
public class DogList : AnimalList<Dog> {}

public class AnimalList<TAnimal> : List<TAnimal> where TAnimal : Animal
{
} 

public class Cat : Animal 
{
    public override void Speak() { "Meow".Dump(); }
}
public class Dog : Animal
{
    public override void Speak() { "Woof".Dump(); }
}

public abstract class Animal 
{
    public abstract void Speak();
}

回到你的例子,如果编译(我不知道你想要的是什么),如果你把它改成:

var t = new Test<MasterBase<ClientBase>>();

答案 1 :(得分:2)

不知道您正在使用哪些约束,最初将其作为评论发布。

public class Test<MasterClass,U> where MasterClass : MasterBase<U> where U: ClientBase

对您的代码库进行适当的更改?显然,这条线也必须改变:

var t = new Test<MasterA,ClientA>();

问题在于,仅仅因为两个类XY之间存在继承关系,这并不意味着通用类型G<X>G<Y>具有相同(或任何)继承关系。因此MasterBase<ClientA> 继承自MasterBase<ClientBase>