TechTalkz.com Logo Ask the Expert

Go Back   TechTalkz.com Technology & Computer Troubleshooting Forums > Tech Support Archives > Programing Languages > C#(C Sharp)

Suggestions? Returning subclass instances from parent class methods

C#(C Sharp)


Reply
 
LinkBack Thread Tools Display Modes
Old 17-10-2007, 02:38 PM   #1
Niels Ull
Guest
 
Posts: n/a
Suggestions? Returning subclass instances from parent class methods

Hi!

I have a generic abstract base class MyCollection<T> which represents a collection
of T's with some common utility methods.
I then have a number of non-generic subclasses, e.g.

class FooCollection : MyCollection<Foo>
{ /* utility methods only for foo collections */ }


class BarCollection : MyCollection<Bar>
{ /* utility methods only for Bar collections */ }


Now, I'd like to provide a subset method in MyCollection - e.g. for getting
the first 10 items
(In real life selecting the subset is more complex and based on the structure
of MyCollection as well as properties of the T base type)

FooCollection allFoos = ...
FooCollection tenFoos = allFoos.GetSubset(10);

But I'd like to return a FooCollection - not a MyCollection<Foo>. The best
I have been able to come up is this method in MyCollection:


DERIVEDCOLLECTION GetSubset<DERIVEDCOLLECTION>(int count) where DERIVEDCOLLECTION:
MyCollection<T>, new()
{
DERIVEDCOLLECTION result = new DERIVEDCOLLECTION();
for(int i = 0; i < count; i++) // example logic only!
result.Add(this[i]);
return result;
}

This is not very elegant, since it requires the user to specify the target
class:
FooCollection tenFoos = allFoos.GetSubset<FooCollection>(10);


An alternative would be to return an IEnumerable<T>, but that would require
the user to write

FooCollection allFoos = ...
FooCollection tenFoos = new FooCollection();
tenFoos.AddAll(allFoos.GetSubset(10))

Or, finally, I could implement new GetSubset in all derived collections -
but since there are a number of such functions, that's not too useful either.

Does anybody have any suggestions?


  Reply With Quote
Old 18-10-2007, 10:36 AM   #2
Adam Clauss
Guest
 
Posts: n/a
Re: Suggestions? Returning subclass instances from parent class methods

One possibility, add a second type to the generic parameters:

class FooCollection : MyCollection<Foo, FooCollection>
{}

where MyCollection is now something like:

class MyCollection<T,S> where S : new()
{
public S GetSubset(int count)
{
S newCollection = new S();
for (int i = 0; i < count; i++)
{
newCollection.Add(this[i]);
}
return newCollection;
}
}

This would then simplify the callers syntax to simply:

FooCollection tenFoos = allFoos.GetSubset(10);

Which was what you wanted correct?

This comes with an assumption: that each of your subclasses has a default
constructor (presumably to create an empty collection).

--
Adam Clauss


"Niels Ull" <nielsull@hotmail.com> wrote in message
news:97b66c3d363bc8c9debe96df98c8@msnews.microsoft .com...
> Hi!
>
> I have a generic abstract base class MyCollection<T> which represents a
> collection of T's with some common utility methods. I then have a number
> of non-generic subclasses, e.g.
>
> class FooCollection : MyCollection<Foo>
> { /* utility methods only for foo collections */ }
>
>
> class BarCollection : MyCollection<Bar>
> { /* utility methods only for Bar collections */ }
>
>
> Now, I'd like to provide a subset method in MyCollection - e.g. for
> getting the first 10 items
> (In real life selecting the subset is more complex and based on the
> structure of MyCollection as well as properties of the T base type)
>
> FooCollection allFoos = ...
> FooCollection tenFoos = allFoos.GetSubset(10);
>
> But I'd like to return a FooCollection - not a MyCollection<Foo>. The best
> I have been able to come up is this method in MyCollection:
>
>
> DERIVEDCOLLECTION GetSubset<DERIVEDCOLLECTION>(int count) where
> DERIVEDCOLLECTION: MyCollection<T>, new()
> {
> DERIVEDCOLLECTION result = new DERIVEDCOLLECTION();
> for(int i = 0; i < count; i++) // example logic only!
> result.Add(this[i]);
> return result;
> }
>
> This is not very elegant, since it requires the user to specify the target
> class: FooCollection tenFoos = allFoos.GetSubset<FooCollection>(10);
>
>
> An alternative would be to return an IEnumerable<T>, but that would
> require the user to write
>
> FooCollection allFoos = ...
> FooCollection tenFoos = new FooCollection();
> tenFoos.AddAll(allFoos.GetSubset(10))
>
> Or, finally, I could implement new GetSubset in all derived collections -
> but since there are a number of such functions, that's not too useful
> either.
>
> Does anybody have any suggestions?
>
>



  Reply With Quote
Old 18-10-2007, 10:36 AM   #3
Adam Clauss
Guest
 
Posts: n/a
Re: Suggestions? Returning subclass instances from parent class methods

Realized I forgot one more thing before that will work.
> S newCollection = new S();
> newCollection.Add(this[i]);


In order to call newCollection.Add(), we need the compiler to know that S
actually derives from MyCollection, more specifically MyCollection of the
same type (T). So change the MyCollection definition to:
class MyCollection<T,S> where S : MyCollection<T,S>, new()

It looks a bit redundant, but it ties all the appropriate things together to
let the compiler know that anything of type S is effectively the same as
itself.

--
Adam Clauss


"Adam Clauss" <cabadam@gmail.com> wrote in message
news:4716e070$0$11090$4c368faf@roadrunner.com...
> One possibility, add a second type to the generic parameters:
>
> class FooCollection : MyCollection<Foo, FooCollection>
> {}
>
> where MyCollection is now something like:
>
> class MyCollection<T,S> where S : new()
> {
> public S GetSubset(int count)
> {
> S newCollection = new S();
> for (int i = 0; i < count; i++)
> {
> newCollection.Add(this[i]);
> }
> return newCollection;
> }
> }
>
> This would then simplify the callers syntax to simply:
>
> FooCollection tenFoos = allFoos.GetSubset(10);
>
> Which was what you wanted correct?
>
> This comes with an assumption: that each of your subclasses has a default
> constructor (presumably to create an empty collection).
>
> --
> Adam Clauss
>
>
> "Niels Ull" <nielsull@hotmail.com> wrote in message
> news:97b66c3d363bc8c9debe96df98c8@msnews.microsoft .com...
>> Hi!
>>
>> I have a generic abstract base class MyCollection<T> which represents a
>> collection of T's with some common utility methods. I then have a number
>> of non-generic subclasses, e.g.
>>
>> class FooCollection : MyCollection<Foo>
>> { /* utility methods only for foo collections */ }
>>
>>
>> class BarCollection : MyCollection<Bar>
>> { /* utility methods only for Bar collections */ }
>>
>>
>> Now, I'd like to provide a subset method in MyCollection - e.g. for
>> getting the first 10 items
>> (In real life selecting the subset is more complex and based on the
>> structure of MyCollection as well as properties of the T base type)
>>
>> FooCollection allFoos = ...
>> FooCollection tenFoos = allFoos.GetSubset(10);
>>
>> But I'd like to return a FooCollection - not a MyCollection<Foo>. The
>> best I have been able to come up is this method in MyCollection:
>>
>>
>> DERIVEDCOLLECTION GetSubset<DERIVEDCOLLECTION>(int count) where
>> DERIVEDCOLLECTION: MyCollection<T>, new()
>> {
>> DERIVEDCOLLECTION result = new DERIVEDCOLLECTION();
>> for(int i = 0; i < count; i++) // example logic only!
>> result.Add(this[i]);
>> return result;
>> }
>>
>> This is not very elegant, since it requires the user to specify the
>> target class: FooCollection tenFoos =
>> allFoos.GetSubset<FooCollection>(10);
>>
>>
>> An alternative would be to return an IEnumerable<T>, but that would
>> require the user to write
>>
>> FooCollection allFoos = ...
>> FooCollection tenFoos = new FooCollection();
>> tenFoos.AddAll(allFoos.GetSubset(10))
>>
>> Or, finally, I could implement new GetSubset in all derived collections -
>> but since there are a number of such functions, that's not too useful
>> either.
>>
>> Does anybody have any suggestions?
>>
>>

>
>



  Reply With Quote
Old 19-10-2007, 05:30 PM   #4
Niels Ull
Guest
 
Posts: n/a
Re: Suggestions? Returning subclass instances from parent class methods

Thanks - that trick looks like just what I needed.


  Reply With Quote
Reply

Thread Tools
Display Modes



< Home - Windows Help - MS Office Help - Hardware Support >


New To Site? Need Help?

All times are GMT +5.5. The time now is 04:07 PM.


vBulletin, Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO
Copyright © 2005-2010, TechTalkz.com. All Rights Reserved - Privacy Policy
Valid XHTML 1.0 Transitional