简体   繁体   中英

Does inheritance in generics work the same way as concrete and abstract classes, InvalidCaseException

I have three classes: Post , Post<T> and WallPost .

Post is an abstract class representing a blog post with properties like name , text , user , etc.

The second abstract class is Post<T> , the generic version of post so I can implement a generic GetChildren(T Post) to get the children of a post and build a hierarchal list.

The third class is the concrete ' WallPost ' which is a specific post for a user's profile.

public class WallPost : Post<WallPost>

And finally a Member class which contains a collection of WallPosts .


I wrote a control that takes a collection of posts and displays it in a tree. One of the proerties I have on that control is

public IList<Post<Post>> Posts
        {
            get; set;
        }

(I use generics because I need to get the children, GetChildren(T Post) ). and I set the type parameter as Post so it will accept any class that inherits from post, wallpost, blogpost, etc

Now my problem is that I want to pass a user's collection of WallPosts of type IList<WallPost> to the function and I get this error:

     Unable to cast object of type 'NHibernate.Collection.Generic.
PersistentGenericBag`1[BO.WallPost]'
 to type 'System.Collections.Generic.IList`1[BO.Post`1[BO.Post]]'.

I'm guessing this is because although you can write something like Post p = new WallPost() you can't have List<Post> posts = new List<WallPost>()

Anyways I'm completely baffled and I hope I made myself clear.

Thank you in advance

E

PS I use NHibernate and there is no mention whatsoever of a bag.

You're trying to use generic covariance in a way that is not type-safe.

What would happen if you write

List<WallPost> wallList = new List<WallPost>();
List<Post> pList = wallList;
pList.Add(new OtherPost());        //Not a WallPost!

You can only do with with read-only interfaces ( IEnumerable<Post> ), or arrays.

You need to check your NHibernate mappings. NHibernate is treating your collection as a bag instead of as a list.

From the NHibernate perspective, a list may not be the appropriate choice. A list gives you index-based access to the members of your collection, but you must have a list index column in your table in order for NHibernate to map it as a list.

You should probably check out the NHibernate collection mapping options and choose the one that best matches your case (set, bag, list, etc.).

In order to work, you could use:

public IList<Post<WallPost>> Posts
{
    get; set;
}

and casting when assigning it:

bla.Posts = posts.Cast<Post<WallPost>>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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