473,387 Members | 1,678 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Generics, Collections, Casting

This is a common problem with generics, but I hope someone has found
the best way of solving it.

I have these classes: "Fruit" which is a baseclass, and "Apple" which
is derived. Further I have an "AppleBasket" which is a class that
contains a collection of apples. So, some code:

class Fruit{
}

class Apple : Fruit
{
}

abstract class FruitBasket
{
public void ListFruit()
{
foreach(Fruit fruit in Fruits)
Debug.WriteLine("Hello fruit : "+fruit);
}

abstract ICollection<Fruit> Fruits{ get; }
}

class AppleBasket : FruitBasket
{
// Don't want a <Fruit> collecion here.
private ICollection<Apple> apples;

public ICollection<Fruit> Fruits
{
get{ return apples; } // Can't do this!
}
}
The obvious way is to have a private collection of "Fruit" in the
applebasket, but if I'm doing loads of handling in the Applebasket that
is specific to apples, then I cant do that without casting each fruit
to apple all the time. Not something you want to do *only* because you
have to return the collection as a collection of fruit in one single
property. That would mean that generics really worked to make the code
uglier rather than better.

Also, I cant cast the ICollection<Apple> to ICollection<Fruit> since
they aren't inherited from eachother. Note that the 'AppleBasket' class
in this example isnt supposed to be though of as a collection class or
anything that itself should be generic, like Basket<Apple>, It's just
an unfortunate circumstance of the example...

So how to how to resolve this? any suggestions are welcome...
thanks

Mar 31 '06 #1
5 2895
Hi Anders,

Nice Issue, struggled with that one as well. You can use List<Apple>. A
list implements the non-generic Ilist, so you can cast it to that to
loop through the fruit. You cannot cast List<Apple> to List<Fruit>,
because List<Apple> does not derive from List<Fruit>.

--
Ward Bekker
"Asp.Net Discussions for the Professional Developer"
http://www.dotnettaxi.com

"Free .Net 2.0 C# to/from VB.Net Code Converter"
http://www.dotnettaxi.com/Tools/Converter.aspx
Mar 31 '06 #2


an*************@gmail.com wrote:
class AppleBasket : FruitBasket
{
// Don't want a <Fruit> collecion here.
private ICollection<Apple> apples;

public ICollection<Fruit> Fruits
{
get{ return apples; } // Can't do this!
}
} So how to how to resolve this? any suggestions are welcome...
thanks


Use a casting adapter for ICollection<Apple> to ICollection<Fruit> and
return that:

Something along the lines of:

public class AppleBasket: FruitBasket {
public ICollection<Apple> Apples; // any impl of ICollection<Apple>
public ICollection<Fruit> Fruits
{ get { return new UpcasetedCollection<Apple, Fruit>(Apples); } }
...
}

public class UpcastedCollection<T, R> : ICollection<R> where T : R
{
public readonly ICollection<T> Parent;
public UpcastedCollection(ICollection<T> parent)
{ this.Parent = parent; }
public void Add(R r) { Parent.Add((T)r); }
public void Clear() { Parent.Clear(); }
public bool Contains(R r)
{ return r is T && Parent.Contains((T)r); }
public void CopyTo(R[] rs, int index)
{ foreach (T t in Parent) rs[index++] = t; }
public bool Remove(R r) { return r is T && Parent.Remove((T)r); }
public int Count { get { return Parent.Count; } }
public bool IsReadOnly { get { return Parent.IsReadOnly; } }
public IEnumerator<R> GetEnumerator()
{ foreach (T t in Parent) yield return t; }
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{ return GetEnumerator(); }
}

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Mar 31 '06 #3
Andreas,

If you use generics for your basked I don't see why you need to use
inheritance. Generics my cause problems, but most of the times the problems
comes from rather incorected design.

If you want to use generics from your basked just do:

class FruitBasket<T>
{
private List<T> fruits = new List<T>();
public void ListFruit()
{
foreach (T fruit in Fruits)
Console.WriteLine("Hello fruit : " + fruit);
}

public ICollection<T> Fruits
{
get
{
return fruits;
}
}

}

When you want to create an apple basked then:

FruitBasket<Apple> appleBasket = new FruitBasket<Apple>()

At the very end this what the generics are all about.

The downside ofcourse is that FruitBasket<Apple> and FruitBasket<Orange>
doesn't have common base class, but if you are going for that you don't need
generics.
--
HTH
Stoitcho Goutsev (100)

<an*************@gmail.com> wrote in message
news:11**********************@j33g2000cwa.googlegr oups.com...
This is a common problem with generics, but I hope someone has found
the best way of solving it.

I have these classes: "Fruit" which is a baseclass, and "Apple" which
is derived. Further I have an "AppleBasket" which is a class that
contains a collection of apples. So, some code:

class Fruit{
}

class Apple : Fruit
{
}

abstract class FruitBasket
{
public void ListFruit()
{
foreach(Fruit fruit in Fruits)
Debug.WriteLine("Hello fruit : "+fruit);
}

abstract ICollection<Fruit> Fruits{ get; }
}

class AppleBasket : FruitBasket
{
// Don't want a <Fruit> collecion here.
private ICollection<Apple> apples;

public ICollection<Fruit> Fruits
{
get{ return apples; } // Can't do this!
}
}
The obvious way is to have a private collection of "Fruit" in the
applebasket, but if I'm doing loads of handling in the Applebasket that
is specific to apples, then I cant do that without casting each fruit
to apple all the time. Not something you want to do *only* because you
have to return the collection as a collection of fruit in one single
property. That would mean that generics really worked to make the code
uglier rather than better.

Also, I cant cast the ICollection<Apple> to ICollection<Fruit> since
they aren't inherited from eachother. Note that the 'AppleBasket' class
in this example isnt supposed to be though of as a collection class or
anything that itself should be generic, like Basket<Apple>, It's just
an unfortunate circumstance of the example...

So how to how to resolve this? any suggestions are welcome...
thanks

Mar 31 '06 #4
I've tested the following successfully:

abstract class FruitBasket<T> where T : Fruit
{
public void ListFruit()
{
}

public abstract ICollection<T> Fruits { get; }
}

class AppleBasket : FruitBasket<Apple>
{
private ICollection<Apple> apples;

public override ICollection<Apple> Fruits
{
get { return apples; }
}
}

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Numbskull

Show me your certification without works,
and I'll show my certification
*by* my works.

<an*************@gmail.com> wrote in message
news:11**********************@j33g2000cwa.googlegr oups.com...
This is a common problem with generics, but I hope someone has found
the best way of solving it.

I have these classes: "Fruit" which is a baseclass, and "Apple" which
is derived. Further I have an "AppleBasket" which is a class that
contains a collection of apples. So, some code:

class Fruit{
}

class Apple : Fruit
{
}

abstract class FruitBasket
{
public void ListFruit()
{
foreach(Fruit fruit in Fruits)
Debug.WriteLine("Hello fruit : "+fruit);
}

abstract ICollection<Fruit> Fruits{ get; }
}

class AppleBasket : FruitBasket
{
// Don't want a <Fruit> collecion here.
private ICollection<Apple> apples;

public ICollection<Fruit> Fruits
{
get{ return apples; } // Can't do this!
}
}
The obvious way is to have a private collection of "Fruit" in the
applebasket, but if I'm doing loads of handling in the Applebasket that
is specific to apples, then I cant do that without casting each fruit
to apple all the time. Not something you want to do *only* because you
have to return the collection as a collection of fruit in one single
property. That would mean that generics really worked to make the code
uglier rather than better.

Also, I cant cast the ICollection<Apple> to ICollection<Fruit> since
they aren't inherited from eachother. Note that the 'AppleBasket' class
in this example isnt supposed to be though of as a collection class or
anything that itself should be generic, like Basket<Apple>, It's just
an unfortunate circumstance of the example...

So how to how to resolve this? any suggestions are welcome...
thanks

Mar 31 '06 #5
<an*************@gmail.com> a écrit dans le message de news:
11**********************@j33g2000cwa.googlegroups. com...

| I have these classes: "Fruit" which is a baseclass, and "Apple" which
| is derived. Further I have an "AppleBasket" which is a class that
| contains a collection of apples.

| The obvious way is to have a private collection of "Fruit" in the
| applebasket, but if I'm doing loads of handling in the Applebasket that
| is specific to apples, then I cant do that without casting each fruit
| to apple all the time. Not something you want to do *only* because you
| have to return the collection as a collection of fruit in one single
| property. That would mean that generics really worked to make the code
| uglier rather than better.
|
| Also, I cant cast the ICollection<Apple> to ICollection<Fruit> since
| they aren't inherited from eachother. Note that the 'AppleBasket' class
| in this example isnt supposed to be though of as a collection class or
| anything that itself should be generic, like Basket<Apple>, It's just
| an unfortunate circumstance of the example...
|
| So how to how to resolve this? any suggestions are welcome...

Try the following :

class Fruit
{
}

class Apple : Fruit
{
}

abstract class Basket<fruitT> where fruitT : Fruit
{
public void ListFruit()
{
foreach (fruitT fruit in fruits)
Console.WriteLine("Hello fruit : " + fruit);
}

private IList<fruitT> fruits = new List<fruitT>();

public IList<fruitT> Fruits
{
get { return fruits; }
}
}

class AppleBasket : Basket<Apple>
{

}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Apr 1 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

24
by: Gary van der Merwe | last post by:
Hi When C# 2.0 arrives System.Collections.Specialized.StringCollection will become "obsolete". Will the framework still contain this class, or will there be a C# 1.X to 2.0 conversion utility...
4
by: KC | last post by:
Could some one explain to me the casting rules for sending generic lists, ex. List<Person>, to a function that accepts List<object>? I cannot get the following easy-cheesy app to work. I get the...
2
by: rajivpopat | last post by:
I've been reading a discussion thread at http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_frm/thread/119f8362a9f5ff52 regarding typecasting generic collections to...
8
by: Ashish | last post by:
Hi all, I have interface declared like public IBaseInterface { } then a generic collection like
6
by: nick_nw | last post by:
Hi, What significant advantages do generics give me over passing objects around as 'object' and casting when needed? I was asked this recently and started off by saying, "well of course...
8
by: Kris Jennings | last post by:
Hi, I am trying to create a new generic class and am having trouble casting a generic type to a specific type. For example, public class MyClass<Twhere T : MyItemClass, new() { public...
2
by: Martin Robins | last post by:
Marc has sorted my problem with the collections, however I am now in a new scenario; I am trying to compare a generic property value before setting it as shown below ... public T Value { get {...
3
by: =?Utf-8?B?RnJhbmsgVXJheQ==?= | last post by:
Hi all I have some problems with Crystal Reports (Version 10.2, Runtime 2.0). In Section3 I have added a OLE Object (Bitmap). Now when I open the report in my code I would like to set this...
3
by: Anders Borum | last post by:
Hello, I've worked on an API for quite some time and have (on several occasions) tried to introduce generics at the core abstract level of business objects (especially a hierarchical node). The...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.