Dynamic Cast

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Wildhorn
    New Member
    • Apr 2010
    • 5

    Dynamic Cast

    Code:
    void Whatever(Type ClassType, ArrayList myArrayList)
    {
    ClassType myClass = new ClassType();
    myClass = (ClassType)myArrayList[0];
    }
    How can I make this work? ClassType is the type of an homemade class.
  • tlhintoq
    Recognized Expert Specialist
    • Mar 2008
    • 3532

    #2
    A) Who says that doesn't work? You haven't said it produces an error.
    B) What is in your ArrayList? We have no idea if you are trying to convert a Cat to a Dog or a String to an int

    How about making a constructor in your custom class that takes the information stored in your array elements?

    Comment

    • Wildhorn
      New Member
      • Apr 2010
      • 5

      #3
      It doesnt work, else I would not be asking for help. It just doesnt want to compile. It refuse to take a variable Type for a cast.

      In my arraylist, like I said, are homemade class.

      Comment

      • tlhintoq
        Recognized Expert Specialist
        • Mar 2008
        • 3532

        #4
        The syntax for the cast is legal.
        I'm sure you realize this because you know you can cast a float to an int, in this way for example

        float Yogi = 0.15f;
        int bear = (int)Yogi;

        But the compiler doesn't have a crystal ball. If you have a custom class of "Widget" and an arraylist containing "Gadget"s - The compiler just doesn't know *how* it should cast that.

        You may need to write a custom cast for your different classes.


        Usually I'm working with classes that inherit from a common class, so VIsual Studio can generally do that impliticly (no custom cast function)

        class Mammal
        class Dog : Mammal
        class Cat : Mammal

        Dog myDoberman = new Dog();
        Cat myTabby = (Cat)myDoberman ;// Legal since they are equal classes of same parent

        Comment

        • jkmyoung
          Recognized Expert Top Contributor
          • Mar 2006
          • 2057

          #5
          I think you want Invoke: eg http://msdn.microsoft.com/en-us/libr...(v=VS.71).aspx

          .. I don't understand why you're creating an object and then shortly thereafter overwriting it.

          Code:
                      ConstructorInfo constructorMethod = ClassType.GetConstructor(new Type[0]);
                      object c = constructorMethod.Invoke(new object[0]);
          //Assumes you have a public constructor with no arguments.

          If you're going to run methods on it, you need to use Type.GetMethod( s)() to get the methods you want to run. Is this really necessary, or could you just use some sort of polymorphism instead, as suggested above?

          Comment

          • Wildhorn
            New Member
            • Apr 2010
            • 5

            #6
            This was just an example. I would not write you the whole thing because it does 400 lines long. But I need to dynamically cast something as a type I receive as parameter. Your thing for constructor is nice, but I need to cast something that already have variables saved into it.

            About:

            class Mammal
            class Dog : Mammal
            class Cat : Mammal

            Dog myDoberman = new Dog();
            Cat myTabby = (Cat)myDoberman ;// Legal since they are equal classes of same parent

            That's not it. I dont know that it is a Cat. It could be a Cat, a Dog, an Elephant, an Alien. I dont know beforehand what the cast will be.

            It would be more:

            class Mammal
            class Dog : Mammal
            class Cat : Mammal
            Type myType = typeof(Cat);

            MyType myTabby = (myType)myDober man;

            Which doesnt compile.

            Comment

            • jkmyoung
              Recognized Expert Top Contributor
              • Mar 2006
              • 2057

              #7
              Why do you need the cast? What are you doing that afterwards that needs myTabby to be treated as a dynamic type? Any other function can call typeof on the object to determine what type it is anyways.

              There's probably an easier way to do it.

              Comment

              • Wildhorn
                New Member
                • Apr 2010
                • 5

                #8
                Because I essentially do the same treatment to 3 different class data, so I do not want to have to write 3 times 400 lines of code when only 1 cast need to be changed.

                Comment

                • Christian Binder
                  Recognized Expert New Member
                  • Jan 2008
                  • 218

                  #9
                  If you have the following:
                  MyType myTabby = (myType)myDober man;

                  what are you going to do with myTabby?
                  If you don't know the type of object you're getting,
                  how would you manipulate it's data or execute it's methods?
                  (e.g. Cat can do other things than Dog can do and has other Attributes
                  Both could do the action Walk() sinc they are both mammals but a dog would be able to do the action ClimbUpTree()
                  )

                  So if you just want to do basic things to this objects, you can cast it to their base-class (e.g. (Mammal)myObjec t; )

                  Maybe you can tell what you want to achieve with your program and speak more special about your classes and data and not only about mammals which I think isn't the subject of your program.

                  Comment

                  • Monomachus
                    Recognized Expert New Member
                    • Apr 2008
                    • 127

                    #10
                    Originally posted by Wildhorn
                    Because I essentially do the same treatment to 3 different class data, so I do not want to have to write 3 times 400 lines of code when only 1 cast need to be changed.
                    I would say you got a lot of possibilities.
                    1. You can do an interface ISomething and then make a helper which works with ISomething and inherit all those classes from ISomething.

                    2. Make an abstract class, inherit all those classes from abstract class. Which is not very different from interface but could help because you put all the code which is common in abstract class.

                    3. Add to constructor of those classes a parameter which will indicate the helper which should work with all those classes.

                    Dunno, I just think you should really know what you need to do.

                    Comment

                    • jkmyoung
                      Recognized Expert Top Contributor
                      • Mar 2006
                      • 2057

                      #11
                      Modularization is a little tough when you're starting out.
                      1. Make a list of all the things that you plan to do with all 3 of your classes. Eg maybe there's a toString() method, some sort of descriptor methods, like length or size or colour.

                      2. Write a class that has all of these common functions.

                      At this point I am not sure if you even need more than 1 class.

                      Comment

                      • tlhintoq
                        Recognized Expert Specialist
                        • Mar 2008
                        • 3532

                        #12
                        Are your three different classes all inherited from the same type?
                        I do this with UserControls for industrial scanners.

                        Class ScannerUI : UserControl
                        Class BrandAlpha: ScannerUI
                        Class BrandBravo: ScannerUI

                        In this way I have no problems doing a case exactly as you have described.

                        Comment

                        • Wildhorn
                          New Member
                          • Apr 2010
                          • 5

                          #13
                          No they do not inherit from the same type, but they all have string variables that need to be treated the same way.

                          Anyway, I got a very "dirty" solution that I do not like much but that will do it for the moment. I made a function that receive the class object and with a switch case return an object of the good type and it works now, but it piss me off that I cant on the fly cast stuff when language like LUA allow such task (you dont even need to cast anything, LUA knows what you want).

                          Comment

                          • tlhintoq
                            Recognized Expert Specialist
                            • Mar 2008
                            • 3532

                            #14
                            A) Change it so they do all inherit from the same type
                            B) Write a custom cast for your class as recommended earlier

                            Comment

                            • jkmyoung
                              Recognized Expert Top Contributor
                              • Mar 2006
                              • 2057

                              #15
                              Maybe make a 4th 'utility' class that handles the strings?
                              Code:
                              Object ob;
                              String str;
                              
                              switch (TypeOf(ob)){
                              case TypeOf(Dog):
                                str = (Dog)ob.Tag;
                                break;
                              case TypeOf(Cat):
                                str = (Cat)ob.Tray;
                                break;
                              case TypeOf(Moose):
                                str = (Moose)ob.Antler;
                                break;
                              }
                              
                              Utility.HandleString(str);
                              Actually, not sure if you can use switch on Types, but just an if-else if chain.

                              Comment

                              Working...