Extracting List Objects
-
Afternoon all ! I have populated a list with various animal objects - 'Cat, Dog, Lion, Tiger....' I am stepping through the list in order to have them call specific methods. The Cat & Dog object both have the same method Pet(). None of the other animals in the list have this method. If i implement 2 seperate statments -
foreach (Cat thisCat in zooAnimals.OfType<Cat>())
{
thisCat.pet();
}foreach (Dog thisDog in zooAnimals.OfType<Dog>())
{
thisDog.pet();
}the code will work fine. I would like to know for my own benefit if there's a way to concatenate these statements into 1 i.e
foreach (Cat thisCat in zooAnimals.OfType<Cat>() || Dog thisDog in zooAnimals.OfType<Dog>())
{
thisCat.pet();
thisDog.pet();
}Thanks in advance Neil
-
Afternoon all ! I have populated a list with various animal objects - 'Cat, Dog, Lion, Tiger....' I am stepping through the list in order to have them call specific methods. The Cat & Dog object both have the same method Pet(). None of the other animals in the list have this method. If i implement 2 seperate statments -
foreach (Cat thisCat in zooAnimals.OfType<Cat>())
{
thisCat.pet();
}foreach (Dog thisDog in zooAnimals.OfType<Dog>())
{
thisDog.pet();
}the code will work fine. I would like to know for my own benefit if there's a way to concatenate these statements into 1 i.e
foreach (Cat thisCat in zooAnimals.OfType<Cat>() || Dog thisDog in zooAnimals.OfType<Dog>())
{
thisCat.pet();
thisDog.pet();
}Thanks in advance Neil
The way to do this is to create an interface called
IPettable
with a single methodPet()
. You then implement this interface for Cat, Dog and any other animal you might want to Pet. Your code then becomes:foreach (IPettable pettableAnimal in zooAnimals.OfType<IPettable>())
{
pettableAnimal.pet();
} -
Afternoon all ! I have populated a list with various animal objects - 'Cat, Dog, Lion, Tiger....' I am stepping through the list in order to have them call specific methods. The Cat & Dog object both have the same method Pet(). None of the other animals in the list have this method. If i implement 2 seperate statments -
foreach (Cat thisCat in zooAnimals.OfType<Cat>())
{
thisCat.pet();
}foreach (Dog thisDog in zooAnimals.OfType<Dog>())
{
thisDog.pet();
}the code will work fine. I would like to know for my own benefit if there's a way to concatenate these statements into 1 i.e
foreach (Cat thisCat in zooAnimals.OfType<Cat>() || Dog thisDog in zooAnimals.OfType<Dog>())
{
thisCat.pet();
thisDog.pet();
}Thanks in advance Neil
You could do this by implementing an extra interface and then iterating over this interface. Like this:
interface IHasPetMethod
{
void pet();
}foreach ( IHasPetMethod hasPetMethod in zooAnimals.OfType<IHasPetMethod> )
{
hasPetMethod.pet();}
This makes the intention of the programmer somewhat clearer (if there is a
pet()
method, then call it). But compared with your original approach, it's largely a matter of taste and coding style. Regards Thomaswww.thomas-weller.de Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
Programmer - an organism that turns coffee into software.modified on Wednesday, December 3, 2008 11:26 AM
-
Afternoon all ! I have populated a list with various animal objects - 'Cat, Dog, Lion, Tiger....' I am stepping through the list in order to have them call specific methods. The Cat & Dog object both have the same method Pet(). None of the other animals in the list have this method. If i implement 2 seperate statments -
foreach (Cat thisCat in zooAnimals.OfType<Cat>())
{
thisCat.pet();
}foreach (Dog thisDog in zooAnimals.OfType<Dog>())
{
thisDog.pet();
}the code will work fine. I would like to know for my own benefit if there's a way to concatenate these statements into 1 i.e
foreach (Cat thisCat in zooAnimals.OfType<Cat>() || Dog thisDog in zooAnimals.OfType<Dog>())
{
thisCat.pet();
thisDog.pet();
}Thanks in advance Neil
Not really - because OfType<T> takes a specific type you can't interchange between Dog and Cat unless they share some common type (other than 'Animal' which I'm assuming is your base type). My preference would be that Cat and Dog both implement an IPet interface:
internal interface IPet { void Pet(); }
so that when you're doing your look you callforeach (IPet pet in zooAnimals.Oftype()) { pet.Pet(); }
FWIW, I assume you're usingyield return
in your OfType<t> - it's more efficient than creating an intermediary IEnumerable object to store the results before returning them? HTHIt definitely isn't definatley
-
Afternoon all ! I have populated a list with various animal objects - 'Cat, Dog, Lion, Tiger....' I am stepping through the list in order to have them call specific methods. The Cat & Dog object both have the same method Pet(). None of the other animals in the list have this method. If i implement 2 seperate statments -
foreach (Cat thisCat in zooAnimals.OfType<Cat>())
{
thisCat.pet();
}foreach (Dog thisDog in zooAnimals.OfType<Dog>())
{
thisDog.pet();
}the code will work fine. I would like to know for my own benefit if there's a way to concatenate these statements into 1 i.e
foreach (Cat thisCat in zooAnimals.OfType<Cat>() || Dog thisDog in zooAnimals.OfType<Dog>())
{
thisCat.pet();
thisDog.pet();
}Thanks in advance Neil
There are genreally two diffrerent approaches to this, and either might make sense in this case. 1. (As suggested already in the thread) You can create in interface IPettable and make the Cat and Doc implement the interface. Then you can check if the object implements the interface:
foreach (Animal animal in zooAnimals) {
IPettable pettable = animal as IPettable;
if (pettable != null) pettable.Pet();
}2. You can make a common base type for domestic animals:
public abstract class DomesticAnimal : Animal {
public virtual void Pet();
}Now you make the Cat and Doc classes inherit DomesticAnimal instead of Animal, and implement the Pet method. You can also implement the Pet method in the DomesticAnimal class if the implementation is the same for Cat and Dog.
foreach (Animal animal in zooAnimals) {
DomesticAnimal domestic = animal as DomesticAnimal;
if (domestic != null) domestic.Pet();
}Despite everything, the person most likely to be fooling you next is yourself.
-
Not really - because OfType<T> takes a specific type you can't interchange between Dog and Cat unless they share some common type (other than 'Animal' which I'm assuming is your base type). My preference would be that Cat and Dog both implement an IPet interface:
internal interface IPet { void Pet(); }
so that when you're doing your look you callforeach (IPet pet in zooAnimals.Oftype()) { pet.Pet(); }
FWIW, I assume you're usingyield return
in your OfType<t> - it's more efficient than creating an intermediary IEnumerable object to store the results before returning them? HTHIt definitely isn't definatley
-
OfType is an extension method, not one the OP has created. http://msdn.microsoft.com/en-us/library/bb360913.aspx[^]
Maybe it's about time I looked at C# 3.0 - and convinced my clients to go down the same road!!
It definitely isn't definatley