By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,028 Members | 1,092 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,028 IT Pros & Developers. It's quick & easy.

Some cast problem and something about generic

P: n/a
Hello!

Below I have a complete working program.with some simple classes one of
these is a generic class.

The question is about this method GetCows() {...} which is a member in the
generic class.
I have two questions about this method.
Question number 1:
If I use "(Cow)animal" insted of "animal as Cow" I get the following compile
error
Error 1 Cannot convert type 'T' to 'ConsoleApplication15.Cow'
C:\tony\ConsoleApplication15\ConsoleApplication15\ Program.cs 115 38
ConsoleApplication15
Why ?
But If I change the foreach clause to foreach (Animal animal in animals)
{...}
I can use this cast "(Cow)animal"
Normally I can use which ever of these cast principle (Cow)animal or animal
as Cow
but not here because I'm forced to use the animal as Cow
Question number 2:
I have the generic class Farm containing Animal(i.e is a Animal)
Why is it not possible to have this foreach in GetRows()
like this
foreach (Cow animal in animals)
{...}
If I do I get the following compile error
Error 1 Cannot convert type 'T' to 'ConsoleApplication15.Cow'
C:\tony\ConsoleApplication15\ConsoleApplication15\ Program.cs 114 13
ConsoleApplication15
Why ?
I can have foreach (Animal animal in animals)
public Farm<Cow GetCows()
{
Farm<CowcowFarm = new Farm<Cow>();
foreach (T animal in animals)
if (animal is Cow)
cowFarm.animals.Add(animal as Cow);

return cowFarm;
}


using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;

namespace ConsoleApplication15
{
class Program
{
static void Main(string[] args)
{
Farm<Animalfarm = new Farm<Animal>();
farm.Animal.Add(new Cow("Jack"));
farm.Animal.Add(new Chicken("Vera"));
farm.Animal.Add(new Chicken("Sally"));
farm.Animal.Add(new SuperCow("Kevin"));

farm.MakeNoises();

Farm<CowdairyFarm = farm.GetCows();
dairyFarm.FeedTheAnimals();

foreach (Cow cow in dairyFarm)
if (cow is SuperCow)
((SuperCow)cow).Fly();

Farm<AnimalnewFarm = farm + dairyFarm;
Console.ReadKey();
}
}

public abstract class Animal
{
string name;
public Animal(string name)
{ this.name = name; }

public string Name
{ get { return name; } }

public abstract void MakeANoise();
public abstract void Feed();
}

public class Chicken : Animal
{
public Chicken(string name) : base(name) {}

public override void MakeANoise()
{ Console.WriteLine("{0} says 'cluck!'", Name); }

public override void Feed()
{ Console.WriteLine("{0} has been feed(Chicken)", Name); }
}

public class Cow : Animal
{
public Cow(string name) : base(name) {}

public override void MakeANoise()
{ Console.WriteLine("{0} says 'moo!'", Name); }

public override void Feed()
{ Console.WriteLine("{0} has been feed(Cow)", Name); }
}

public class SuperCow : Cow
{
public SuperCow(string name) : base(name) {}

public void Fly()
{ Console.WriteLine("{0} is flying!", Name); }

public override void MakeANoise()
{ Console.WriteLine("{0} says 'here I come to save the day!'",
Name); }

public override void Feed()
{ Console.WriteLine("{0} has been feed(SuperCow)", Name); }
}

public class Farm<T: IEnumerable<T>
where T : Animal
{
private List<Tanimals = new List<T>();

public List<TAnimal
{ get { return animals; } }

public IEnumerator<TGetEnumerator()
{ return animals.GetEnumerator(); }

IEnumerator IEnumerable.GetEnumerator()
{ return animals.GetEnumerator(); }
public void MakeNoises()
{
foreach (T animal in animals)
animal.MakeANoise();
}

public void FeedTheAnimals()
{
foreach (T animal in animals)
animal.Feed();
}

public Farm<CowGetCows()
{
Farm<CowcowFarm = new Farm<Cow>();
foreach (T animal in animals)
if (animal is Cow)
cowFarm.animals.Add(animal as Cow);
return cowFarm;
}

public static Farm<Toperator +(Farm<Tfarm1, Farm<Tfarm2)
{
Farm<Tresult = new Farm<T>();
foreach (T animal in farm1)
result.Animal.Add(animal);

foreach (T animal in farm2)
if (!result.Animal.Contains(animal))
result.Animal.Add(animal);
return result;
}

public static implicit operator Farm<Animal>(Farm<Tfarm)
{
Farm<Animalresult = new Farm<Animal>();

foreach(T animal in farm)
result.Animal.Add(animal);
return result;
}
}
}

//Tony
Jun 27 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On Jun 19, 10:39*am, "Tony" <johansson.anders...@telia.comwrote:
Hello!

Below I have a complete working program.with some simple classes one of
these is a generic class.

The question is about this method GetCows() {...} which is a member in the
generic class.
I have two questions about this method.
Question number 1:
If I use "(Cow)animal" insted of "animal as Cow" I get the following compile
error
Error 1 Cannot convert type 'T' to 'ConsoleApplication15.Cow'
I don't know. Oddly enough, you *can* do:

(Cow)(Animal)animal;

There's an implicit conversion from T to animal, so I would have
expected it to work.

I'll delve into the spec to see what's going on. It could just be a
compiler bug.

Jon
Jun 27 '08 #2

P: n/a
Hello!

What about question number 2 in the previous mail?

//Tony
"Jon Skeet [C# MVP]" <sk***@pobox.comskrev i meddelandet
news:4b**********************************@r66g2000 hsg.googlegroups.com...
On Jun 19, 10:39 am, "Tony" <johansson.anders...@telia.comwrote:
Hello!

Below I have a complete working program.with some simple classes one of
these is a generic class.

The question is about this method GetCows() {...} which is a member in the
generic class.
I have two questions about this method.
Question number 1:
If I use "(Cow)animal" insted of "animal as Cow" I get the following
compile
error
Error 1 Cannot convert type 'T' to 'ConsoleApplication15.Cow'
I don't know. Oddly enough, you *can* do:

(Cow)(Animal)animal;

There's an implicit conversion from T to animal, so I would have
expected it to work.

I'll delve into the spec to see what's going on. It could just be a
compiler bug.

Jon
Jun 27 '08 #3

P: n/a
On Jun 19, 11:14*am, "Tony" <johansson.anders...@telia.comwrote:
What about question number 2 in the previous mail?
It's basically the same thing, I expect. Think of foreach as
implicitly inserting a cast - it's translating (ignoring disposal etc)
the code into:

IEnumerator<Titerator = animals.GetEnumerator();
while (iterator.HasNext)
{
Cow cow = (Cow) iterator.Current;
// Your code here
}

The cast is failing in the same was as it did within the loop.

Just my current theory, anyway...

Jon
Jun 27 '08 #4

P: n/a
I don't know. Oddly enough, you *can* do:
>
(Cow)(Animal)animal;

There's an implicit conversion from T to animal, so I would have
expected it to work.

I'll delve into the spec to see what's going on. It could just be a
compiler bug.
I think it's because a cast can be either a runtime type check or an
op_Explicit call. It's the runtime type check when casting to a direct
ancestor or descendant in the inheritance tree. But Cow and T are both
descendants of Animal, and it would be legal, for any given T more loosely
related to Cow, to define an op_Explicit returning Cow. So the compiler
interprets the cast as the op_Explicit call, searches the constraints, finds
none such defined, and fails.
>
Jon

Jul 18 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.