Home > Mobile >  C#: After using "as" keyword to convert object's type to the interface it implements,
C#: After using "as" keyword to convert object's type to the interface it implements,

Time:03-12

Class diagram for the code below: HoneyManufacturer class and NectarCollector class both extend Bee class. Bee class implements interface IWorker.

IWorker[] bees = new IWorker[8];
bees[0] = new HoneyManufacturer();
bees[1] = new NectarCollector();
bees[2] = bees[0] as IWorker;   // bees[2] is of type HoneyManufacturer, why?
bees[3] = bees[1] as NectarCollector;
bees[4] = IWorker;
bees[5] = bees[0];
bees[6] = bees[0] as Object;
bees[7] = new IWorker();

So I understand that the bees[4] and bees[7] lines won't compile because interfaces cannot be instantiated. I still have the following questions:

  1. For the bees[2] line, my understanding is that the "as" keyword converts bees[0] to IWorker type since HoneyManufacturer class extends Bee class which implements IWorker interface. But bees[2] is still of type HoneyManufacturer (I've checked in my program), why?

  2. For the bees[6] line, book says it will compile but it doesn't compile in my Visual Studio 2022. Why?

I've already read so many other posts about casting and type conversion but I cannot find the answer to my specific question.

Thank you so much for your help!


Edit: (since I couldn't reply too long as a comment)

Thank you so much for your answers, really really appreciate it!!!

So do you mean that bees[2] = bees[0] as IWorker is only casting the reference variable, but not the object?

I checked the type of bees[2] with this code afterwards and it returns TRUE for all three.

Console.WriteLine(bees[2] is Bee);
Console.WriteLine(bees[2] is HoneyManufacturer);
Console.WriteLine(bees[2] is IWorker);

I thought that bees[2] would've been converted to IWorker and thus no longer of type HoneyManufacturer. Is there any circumstance when we actually need to do something like bees[2] = bees[0] as IWorker?

The book I'm reading is Head First C# and this is an exercise on page 381. It asks me to pick out the lines that won't compile and gives the answer of the bees[4] line and the bees[7] line. Then it asks which values of i would make this evaluate to TRUE:

(bees[i] is Bee)

The answer given is 0, 1, 2, 3, 5, 6 and I didn't understand why bees[2] is Bee.

CodePudding user response:

Typecasts of reference types do not convert anything. (Typecasts of value types are a different story.)

A typecast of a reference type just acts as promise that the right-hand-side can be assigned to the left-hand side. You are giving this promise to the compiler, so that the compiler will agree to compile your code, and if the promise turns out to be false at runtime, you will be slapped with a type-cast exception.

So:

1: the "as" keyword does not convert bees[0] to IWorker type, it just promises that bees[0] can be assigned to a variable of IWorker type, which is an entirely redundant promise to give, since bees[0] is already of IWorker type. You say you checked in your program; how did you check? what did you find? what did you expect?

2: What book says that? Exactly what does the book say? The statement bees[6] = bees[0] as Object; could never possibly compile because you are promising that bees[0] is an Object, which is again an entirely redundant promise to give, since bees[0] is of course of type Object, but you cannot assign that to bees[6], because bees[6] expects an IWorker, not an Object. Even though IWorker can be assigned to Object, the opposite is not true: Object cannot be assigned to IWorker. If you do not understand this, then you will not find your answer on Stackoverflow; you will need to study how the type systems of Object-Oriented Languages like C# work.

CodePudding user response:

There is needless convolution here with the array. I think you could use a bit of practice with inheritance and interfaces, and "is" and "as".

Check out this example I wrote up: https://dotnetfiddle.net/f37jNX

  • Related