|
-
Nov 14th, 2002, 03:56 AM
#1
Thread Starter
Hyperactive Member
CType function
Hi eveybody,
I want to know about working of CType function. When one object is converted other type, what happens to its member variables? I mean how are private member variables and functions treated in this conversion?
Thanks in advance.
Abhid
-
Nov 14th, 2002, 08:48 AM
#2
PowerPoster
When casting between types, you can only cast between compatible types (up cast). My example is in C#, if you have problems interpreting the code let me know. I post all my code in C# to help everyone learn and read between .NET languages. It's helped me out alot.
Code:
class Automobile
{
public void TurnRight(){};
public void TurnLeft(){};
}
class Car : Automobile
{
public string manufacturer;
}
// perform cast operation
// Note, I only have access to the automobile member functions
// through its public interface.
Car myCar = New Car();
Automobile myAuto = myCar;
myAuto.Manufacturer = "Audi"; // Compiler will puke on this...
-
Nov 15th, 2002, 01:23 PM
#3
Hyperactive Member
technically you did not perform the cast which is why the compiler would "puke" on that line.
Code:
Car myCar = New Car();
Automobile myAuto = myCar; //this is not a cast
the cast would be on this line:
Code:
((Car)myAuto).Manufacturer = "Audi";
but remember, you initialized myAuto to the instance of myCar. So casting on the line above changes the value of Manufacturer on the myCar variable by doing that cast. Run the following code to test:
Code:
using System;
namespace Casting
{
public class MainApp
{
public static void Main(string[] args)
{
Car myCar = new Car();
Automobile myAuto = myCar;
myCar.Manufacturer = "honda";
//the following will write out: myCar is a honda
Console.WriteLine("myCar is a {0}", myCar.Manufacturer);
//Cast myAuto as a Car
((Car)myAuto).Manufacturer = "ford";
//the following will write out: myCar is now a ford
Console.WriteLine("myCar is now a {0}", myCar.Manufacturer);
Console.ReadLine();
}
}
class Automobile
{
public void TurnRight()
{
Console.WriteLine("Turning Right...");
}
public void TurnLeft()
{
Console.WriteLine("Turning Left...");
}
}
class Car : Automobile
{
public string Manufacturer;
}
}
-
Nov 16th, 2002, 11:30 AM
#4
PowerPoster
technically you did not perform the cast which is why the compiler would "puke" on that line.
Yeah, I know all that but I just wrote up a simple example to show the basic concept. Also, the line you pointed out is in fact a cast (implicit), it does not need to be explicit b/c it is an upcast..
-
Nov 16th, 2002, 02:01 PM
#5
Hyperactive Member
I think there's a little confusion between implicit and explicit conversions and casting.
An implicit conversion means that you do not need a cast. Typically you'll see this when assigning the value of a variable of type int the value of a variable of type short. Example:
Code:
short x = 2;
int y = x; //implicit conversion, widening scope, no casting required
the following will not compile because implicit conversions do not work on narrowing scope:
Code:
int x = 10;
short y = x // generates compile time error, implicit conversion not allowed
The above would work using a cast:
Code:
int x = 10;
short y = (short)y; //explicit conversion, narrowing scope, ok with a cast
VB.NET let's you get away without the cast: this compiles fine:
VB Code:
Dim x As Integer = 10
Dim y As Short = x
So narrowing and widening conversions basically take place with numbers. When you're casting objects like cars and vehicles there's no narrowing, widening, upcasting, downcasting, or whatever term you wanna use. What you're doing in this case asking one object to behave like a specific object if it supports that specific object/interface. Check out the following example:
Code:
using System;
namespace Casting
{
public class MainApp
{
public static void Main(string[] args)
{
Car honda = new Car();
Truck ford = new Truck();
TurnVehicleRight(honda);
TurnVehicleRight(ford);
//The following line will compile, and in fact "Hello" can
//be sent into the method, but as soon as the cast is
//executed an exception will be thrown. Uncomment following
//line to see.
//TurnVehicleRight("Hello");
Console.ReadLine();
}
public static void TurnVehicleRight(object arg)
{
// Need to tell arg to put on it's Vehicle "hat" if it has one.
// If no Vehicle "hat" supported it will throw an InvalidCastException.
Vehicle v = (Vehicle)arg;
v.TurnRight();
}
}
public class Truck : Vehicle
{
//constructor
public Truck()
{
base.VehicleType = "Truck";
}
}
public class Car : Vehicle
{
//constructor
public Car()
{
base.VehicleType = "Car";
}
}
public class Vehicle
{
private string vehicleType = "Vehicle";
public string VehicleType
{
get { return vehicleType; }
set { vehicleType = value; }
}
public void TurnRight()
{
Console.WriteLine("Your {0} is turning right...", vehicleType );
}
public void TurnLeft()
{
Console.WriteLine("Your {0} is turning left...", vehicleType);
}
}
}
The line that does the casting is this one:
Code:
Vehicle v = (Vehicle)arg;
It's not doing anything except telling arg to act as a Vehicle. If arg does not support the Vehicle interface it will throw an exception. During the cast any private member variables and values will remain unaffected, i think that answers the original question too. You can also test for a supported interface like the following:
Code:
public static void TurnVehicleRight(object arg)
{
// Check to see if arg supports the Vehicle interface before casting.
if (arg is Vehicle)
{
Vehicle v = (Vehicle)arg;
v.TurnRight();
}
else
Console.WriteLine("Vehicle interface not supported!");
}
-
Nov 16th, 2002, 02:12 PM
#6
Hyperactive Member
here's the above example in VB.NET "speak":
VB Code:
Namespace Casting
Public Class MainApp
Public Shared Sub Main(ByVal args As String())
Dim honda As New Car()
Dim ford As New Truck()
TurnVehicleRight(honda)
TurnVehicleRight(ford)
TurnVehicleRight("hello")
Console.ReadLine()
End Sub
Public Shared Sub TurnVehicleRight(ByVal arg As Object)
If TypeOf arg Is Vehicle Then
Dim v As Vehicle = CType(arg, Vehicle)
v.TurnRight()
Else
Console.WriteLine("Vehicle interface not supported!")
End If
End Sub
End Class
Public Class Truck : Inherits Vehicle
Public Sub New()
MyBase.VehicleType = "Truck"
End Sub
End Class
Public Class Car : Inherits Vehicle
Public Sub New()
MyBase.VehicleType = "Car"
End Sub
End Class
Public Class Vehicle
Private _vehicleType As String = "Vehicle"
Public Property VehicleType() As String
Get
Return _vehicleType
End Get
Set(ByVal Value As String)
_vehicleType = Value
End Set
End Property
Public Sub TurnRight()
Console.WriteLine("Your {0} is turning right ... ", _vehicleType)
End Sub
Public Sub TurnLeft()
Console.WriteLine("Your {0} is turning left ... ", _vehicleType)
End Sub
End Class
End Namespace
-
Nov 16th, 2002, 02:28 PM
#7
PowerPoster
When you're casting objects like cars and vehicles there's no narrowing, widening, upcasting, downcasting, or whatever term you wanna use.
Sorry, but I do not totally agree with this statement. You can cast an object of a derived class to the base class (known as upcasting) and vice versa. However, you can only cast an object to a class when that class is compatible with the object's class. Upcasting and downcasting are familiar terms used in the OOP community. Many developers use the term 'conversion' and 'casting' interchangeably, which isn't always a good thing. As you know, the framework is made up of all different types. When explicitly converting between types, regardless of value type or reference type, you are casting. Hence, in order to perform a narrowing conversion, you have to use the cast operator.
Last edited by Lethal; Nov 16th, 2002 at 02:39 PM.
-
Nov 16th, 2002, 02:51 PM
#8
Hyperactive Member
Well, i've never heard the terms upcasting and downcasting, so my bad, i hear what you're saying. Use whatever terminology you want the fact still remains that when you're casting objects like cars and vehicles you are merely putting on a different interface to interact with and that's it. But when you're doin the same with numbers you are in fact changing values(if it's needed) to make the cast work. A number can't put on a different interface because it doesn't really have one to begin with, it's a value type and contains only a value.
So to sum up, if you're casting a car object variable to a vehicle type you're telling the car variable to show it's Vehicle face, but no data in the object has changed, the car is now just acting as a Vehicle. BUT, casting an int value to a short value doesn't put on a different interface, it actually changes the value(if it needs to) and assigns the new value to the short variable which is where the narrowing scope is encountered.
Converting between types, regardless of value type or reference types is casting (if not an implicit conversion)
I agree, BUT what actually happens during the casting is absolutely different depending on what you're doing. Casting numbers to numbers can change values through a cast, casting objects to objects changes interfaces through a cast but doesn't change the underlying data.
-
Nov 16th, 2002, 02:57 PM
#9
PowerPoster
Yes, I agree with everything you are saying, but I was only stressing that casting is done regardless of the type. But like you stated, what the cast actually does is different depending upon whether we are using value types or ref types.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|