Cannot convert type when using a custom generic collection

I have a base entity class, and a generic collection class constrained to use the entity class.

I then created a subclass of each, FFAccount and FFAccountCollection.

All is well until I try to use the generic class with in the program.  I am trying to assign an instance of the  FFAccountCollection class to a property based on the generic base class.


// the base classes
public class SWBase{}
 
public class SWCollectionBase<T> : List<T> where T : SWBase{}
 
 
// the sub classes
public class FFAccount : SWBase{}
 
public class FFAccountCollection : SWCollectionBase<FFAccount>{}
 
 
class Test
 {
   // A property based on the base generic collection
   public SWCollectionBase<SWBase> BusinessObjCollection;
 }
  
  
void RunIt()
 {
   FFAccountCollection amgc = new FFAccountCollection();
  	
   Test tst = new Test();
   tst.BusinessObjCollection = amgc;    ///// ERROR
  }
  
  Error	6	Cannot implicitly convert type 'SWCollectionBase<FFAccount>' to 'SWCollectionBase<SWBase>'

Open in new window

DanielPatAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

drichardsCommented:
Test.BusinessObjectCollection is of type SWCollectionBase<SWBase>, while FFAccountCollection is derived from SWCollectionBase<FFAccount>, so you can't set BusinessCollection to amgc in your code as they are different types not related by inheritance.  You'd have to derive FFAccountCollection from SWCollectionBase<SWBase>.  You could still add FFAccount objects to this collection as FFAccount derives from SWBase, but you'd only get access to the SWBase interface on collection members unless you did casts to FFAccount.

What exactly are you trying to accomplish?
0
DanielPatAuthor Commented:
I thought I would be able to do exactly what you tell me I cannot!  In otherwords, add FFAccount objects to the collection and access properties of both FFAccount and the base class.  

Should I be using an interface to represent the base class instead?

In otherwords something like this:

public class SWCollectionBase<T> : List<T> where T : ISWBase{}


0
trunghieubkitCommented:
You can assign directly

tst.BusinessObjCollection = amgc;

You can fix by using a loop and assign each item of list instead

void RunIt()
{
	FFAccountCollection amgc = new FFAccountCollection();
 
	Test tst = new Test();
	foreach(FFAccount ff in amgc)
	{
		tst.BusinessObjCollection.Add(ff);
	}
}

Open in new window

0
drichardsCommented:
Assigning each member individuallin a loop as trunghieubkit suggests is a possibiilty, although I doubt it is what you are after since you now have two collections instead of one.  In fact, you'd have to add a line:

    tst.BusinessObjCollection = new SWCollectionBase<SWBase>();

prior to the foreach to avoid a null reference exception.

Using an interface is not going to help you since you will still have exactly the same problem.  The basic problem is that you have defined two different list types (via generics) that have compatible member items, which is why the individual member copy works, but the collections themselves are of different types.

The only way assigning collection references will work is if the collections are of exactly the same type, which is this case means SWCollectionBase<SWBase>.  You can assign any type derived from SWBase as members of this collection, which may also not be what you want.  You could mix FFAccount objects and any other type derived from SWBase in the same list.

To suggest a better solution, I would have to know what your design parameters are.  As a first cut, I'd say make SWBase an abstract base class or an interface as you suggest, and give it methods that derived classes are required to implement and then just use SWCollectionBase<SWBase> as the collection class.  You don't need FFAccountCollection in that case.  This does leave you with the problem of non-specific collections I mentioned earlier.

The design will be more complex if you want a series of very type specific collections that can be assigned into a Test.BusinessObjCollection.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.