Results 1 to 9 of 9

Thread: CType function

  1. #1

    Thread Starter
    Hyperactive Member abhid's Avatar
    Join Date
    Nov 2001
    Location
    3rd rock from the sun
    Posts
    467

    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

  2. #2
    PowerPoster Lethal's Avatar
    Join Date
    Oct 2000
    Location
    Ohio
    Posts
    2,496
    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...

  3. #3
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fort Collins, CO
    Posts
    366
    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;
    	}
    
    }

  4. #4
    PowerPoster Lethal's Avatar
    Join Date
    Oct 2000
    Location
    Ohio
    Posts
    2,496
    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..

  5. #5
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fort Collins, CO
    Posts
    366
    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:
    1. Dim x As Integer = 10
    2. 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!");
    }

  6. #6
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fort Collins, CO
    Posts
    366
    here's the above example in VB.NET "speak":
    VB Code:
    1. Namespace Casting
    2.  
    3.     Public Class MainApp
    4.  
    5.         Public Shared Sub Main(ByVal args As String())
    6.             Dim honda As New Car()
    7.             Dim ford As New Truck()
    8.             TurnVehicleRight(honda)
    9.             TurnVehicleRight(ford)
    10.             TurnVehicleRight("hello")
    11.             Console.ReadLine()
    12.         End Sub
    13.  
    14.         Public Shared Sub TurnVehicleRight(ByVal arg As Object)
    15.             If TypeOf arg Is Vehicle Then
    16.                 Dim v As Vehicle = CType(arg, Vehicle)
    17.                 v.TurnRight()
    18.             Else
    19.                 Console.WriteLine("Vehicle interface not supported!")
    20.             End If
    21.         End Sub
    22.  
    23.     End Class
    24.  
    25.     Public Class Truck : Inherits Vehicle
    26.         Public Sub New()
    27.             MyBase.VehicleType = "Truck"
    28.         End Sub
    29.     End Class
    30.  
    31.     Public Class Car : Inherits Vehicle
    32.         Public Sub New()
    33.             MyBase.VehicleType = "Car"
    34.         End Sub
    35.     End Class
    36.  
    37.     Public Class Vehicle
    38.         Private _vehicleType As String = "Vehicle"
    39.         Public Property VehicleType() As String
    40.             Get
    41.                 Return _vehicleType
    42.             End Get
    43.             Set(ByVal Value As String)
    44.                 _vehicleType = Value
    45.             End Set
    46.         End Property
    47.         Public Sub TurnRight()
    48.             Console.WriteLine("Your {0} is turning right ... ", _vehicleType)
    49.         End Sub
    50.         Public Sub TurnLeft()
    51.             Console.WriteLine("Your {0} is turning left ... ", _vehicleType)
    52.         End Sub
    53.     End Class
    54.  
    55. End Namespace

  7. #7
    PowerPoster Lethal's Avatar
    Join Date
    Oct 2000
    Location
    Ohio
    Posts
    2,496
    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.

  8. #8
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fort Collins, CO
    Posts
    366
    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.

  9. #9
    PowerPoster Lethal's Avatar
    Join Date
    Oct 2000
    Location
    Ohio
    Posts
    2,496
    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
  •  



Click Here to Expand Forum to Full Width