当前位置: 首页 > 编程语言 > C#

C#泛型继承问题分享

时间:2023-04-10 14:19:07 C#

C#泛型继承问题我想把从泛型派生的不同类型的对象添加到基类型列表中。我得到这个编译错误Error2Argument1:cannotconvertfrom'ConsoleApplication1.Stable'to'ConsoleApplication1.ShelterBase'C:UsersysnDesktopConsoleApplication1ConsoleApplication1Program.cs4326ConsoleApplication1我没有看到问题你能给我提供另一种方法来做这种物法?抽象类AnimalBase{publicintSomeCommonProperty;}抽象类ShelterBase其中T:AnimalBase{publicabstractListGetAnimals();publicabstractvoidFeedAnimals(列出动物);}classHorse:AnimalBase{}classStable:ShelterBase{publicoverridesList(GetAnimals){returnnewList();}publicoverridevoidFeedAnimals(Listanimals){//喂它们}}classDuck:AnimalBase{}classHenHouse:ShelterBase{publicoverrideListGetAnimals(){returnnewList();overridevoidFeedAnimals(Listanimals){//喂它们}}classProgram{staticvoidMain(string[]args){Listshelters=newList();/////////////////////////////以下两行不要编译shelters.Add(newStable());shelters.Add(newHenHouse());///////////////////////////////foreach(避难所中的避难所){varanimals=shelter.GetAnimals();//dosthwith'animals'collection}}}您可以使用逆变,但前提是您将抽象类更改为接口和GetAnimalsGetAnimals的返回类型为IEnumerable,因为List不支持此函数有效代码:抽象类AnimalBase{publicintSomeCommonProperty;}interfaceIShelterBasewhereT:AnimalBase{IEnumerableGetAnimals();}classHorse:AnimalBase{}classStable:IShelterBase{publicIEnumerableGetAnimals(){returnnewList();}}类Duck:AnimalBase{}类HenHouse:IShelterBase{publicIEnumerableGetAnimals(){returnnewList();}}voidMain(){避难所列表=newList>();避难所。添加(新稳定());避难所。添加(新鸡舍());foreach(varshelterinshelters){varanimals=shelter.获取动物();//dosomethingwith'animals'collection}}你可以用协变和逆变来做到这一点,但是你的ShelterBase类需要从接口派生,因为只有接口可以是协变或逆变的。您的列表需要是一个List>并且它应该可以工作。有关详细信息,请参阅此处关于泛型协方差和协方差的文章:http://msdn.microsoft.com/en-us/library/dd799517.aspx要解决此特定问题,您实际上并不需要协方差。当您使用动物列表时,仍然可以通过IShelterBase接口使用AnimalBase。还不如通过基类公开AnimalBase的列表。更好更简洁的设计是让GetAnimals返回GetAnimals的列表,并在每个庇护所类中创建一个重载以返回该特定动物的列表。abstractclassShelterBasewhereT:AnimalBase{publicListGetAnimals(){returnnewList();}}classStable:ShelterBase{publicListGetHorses(){returnnewList();}}这种设计的另一个问题是大多数Derived类型(即List,而不是IEnumerable或IList)公开集合。鉴于您在创建抽象动物集合的类时遇到问题,您应该通过禁止直接插入/删除功能来真正保护内部集合。一旦你这样做了,事情就会变得容易一些。例如,我将如何着手解决这个问题。抽象类ShelterBase其中T:AnimalBase{protectedList_Animals;publicAnimalBase(){_Animals=CreateAnimalCollection();}受保护的抽象列表CreateAnimalCollection();publicIEnumerableGetAnimals(){return_Animals.Cast();}//AddremoveoperationsgoherepublicvoidAdd(Tanimal){_Animals.Add(animal);}publicvoidRemove(Tanimal){_Animals.Remove(animal);}}classStable:ShelterBase{protectedoverrideListCreateAnimalCollection(){returnnewList();}publicIEnumerableGetHorses(){return_Animals;}}你会注意到动物的内部集合永远不会暴露为可变的列表。这很好,因为它允许您更严格地控??制其内容。在此示例中,基本掩体中的Add和Remove方法有点人为,因为它们不会向直接集合访问添加任何额外的内容,但您可以在那里添加逻辑-例如,检查最大掩码大小将其删除.我刚刚遇到了类似的问题。我的所有实体都派生自基类,并且我创建了一个方法来返回连接的ID列表。因此使用泛型创建方法并出现一些转换错误。设法将泛型T转换为Object并将Object转换为BaseClass并进行某种验证以防万一。//需要它在很多派生类中通用使用privateStringConcatIds(ListlistObj){Stringids=String.Empty;foreach(TobjinlistObj){BaseEntitybe=CastBack(obj);如果(ids.Count()>0)ids=ids+String.Format(",{0}",be.Id);否则ids=be.Id.ToString();}返回ID;}//我可能会把它移到基类本身privateBaseEntityCastBack(TgenericObj){Typetype=typeof(T);if(type.BaseType==typeof(BaseEntity)){Object_obj=(Object)genericObj;返回(基础实体)_obj;}else{thrownewInvalidOperationException(String.Format("无法将{0}转换为BaseEntity",type.ToString()));}}用法:publicclassBaseEntity{publicInt32Id{get;set;}}publicclassAnyDerivedClass:BaseEntity{//LoremIpsum}privatevoidDoAnything(ListmyList){Stringids=this.ConcatIds(myList);编辑:过了一会儿我需要创建更多的层次结构级别,有时会回到父母或祖父母。所以我使我的CastBack方法更通用。以上就是C#学习教程:C#泛型继承问题分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注—privateBCastBack(TgenericObj){Typetype=typeof(T);if(type.BaseType==typeof(B)){Object_obj=(Object)genericObj;返回(B)_obj;}else{thrownewInvalidOperationException(String.Format("Cannotcastback{0}",type.ToString()));}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: