Down casting objects

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tem

    Down casting objects

    I have classes A,B,C,D,E,F that implement InterfaceBase.

    Whats the best way to down cast obj to the correct type?

    Is there a more elegant way to do this than?

    Public Void DoSomething(Int erfaceBase obj)
    {
    if(obj is A)
    ((A)obj).Method ThatOnlyACanDo( );
    else if(obj is B)
    ((B)obj).Method ThatOnlyBCanDo( );
    ....
    }

    if and else if can become confusing when more options (more parameters,
    child types) are added.

    Tem

  • cfps.Christian

    #2
    Re: Down casting objects

    I don't know that every method has to have a different name but if you
    created a singular method in the base class and would override it in
    the child classes with the same name you wouldn't have that problem.

    I've run into a similar situation but it was because I needed to save
    the objects differently so I had to know which one I was dealing with.

    Comment

    • Peter Duniho

      #3
      Re: Down casting objects

      On Mon, 14 Apr 2008 13:49:51 -0700, Tem <tem1232@yahoo. comwrote:
      I have classes A,B,C,D,E,F that implement InterfaceBase.
      >
      Whats the best way to down cast obj to the correct type?
      >
      Is there a more elegant way to do this than?
      I would agree with the reply from "cfps.Christian " that it would be much
      better if you could simply declare a common abstract or virtual method in
      the base class that each derived class could override.

      If you really want to do what you're doing, casting it (or using the "as"
      operator) is the only way to get to the derived type. However, if you
      find yourself doing this, there's a very good chance that whatever
      functionality you're trying to implement in your "DoSomethin g()" method
      isn't being done in the best way anyway.

      It's not that it never comes up. Just that it probably doesn't come up
      nearly as often as one might think. If you have a method that "does
      something" and takes some base class that can be inherited by different
      sub-classes, and you expect each sub-class to "do" that "something"
      differently, then the best way to represent that is with a single
      overridden abstract or virtual method in the base class.

      Pete

      Comment

      • Jeff Louie

        #4
        Re: Down casting objects

        Tem... In addition to these suggestions, you could define an interface
        IDoSomeThing and avoid the switch:

        public void DoSomeThingIfPo ssible(Interfac eBase obj) {
        if (obj is IDoSomething) {
        ( (IDoSomeThing)o bj).DoSomething ();
        }
        }

        Regards,
        Jeff

        *** Sent via Developersdex http://www.developersdex.com ***

        Comment

        • Tem

          #5
          Re: Down casting objects

          How would i do that if i have more than 1 parameter?

          Public Void DoSomething(Int erfaceBase obj1,InterfaceB ase obj2)
          {
          if(obj1 is A && obj2 is A)
          Method1(((A)obj 1),((A)obj2);
          else if(obj1 is A && obj2 is B)
          Method2(((A)obj 1),((B)obj2);
          else if(obj1 is A && obj2 is C)
          Method2(((A)obj 1),((C)obj2);.. .

          }
          I have 36 possibilities, if and else if becomes very messy and lots of room
          for making errors.
          Im not sure how to use the method you mentioned with more than 1 parameter.


          "cfps.Christian " <ge0193387@otc. eduwrote in message
          news:3800b33b-4a92-4684-b346-153450f0a774@a2 2g2000hsc.googl egroups.com...
          >I don't know that every method has to have a different name but if you
          created a singular method in the base class and would override it in
          the child classes with the same name you wouldn't have that problem.
          >
          I've run into a similar situation but it was because I needed to save
          the objects differently so I had to know which one I was dealing with.
          >

          Comment

          • Peter Duniho

            #6
            Re: Down casting objects

            On Tue, 15 Apr 2008 19:00:45 -0700, Tem <tem1232@yahoo. comwrote:
            [...]
            I have 36 possibilities, if and else if becomes very messy and lots of
            room for making errors.
            Im not sure how to use the method you mentioned with more than 1
            parameter.
            It would really help if you could explain what it is exactly you're
            doing. Do you literally have 36 different methods that will be called?

            It's possible that the problem can be factored down to something that's
            simpler. But if all we know about the problem is that you have 36
            different possible outcomes, dependent on two different variables, it's
            difficult to see how you'd make it simpler than a straight enumeration of
            the possibilities.

            If we knew more about the problem, it's likely that there's some
            characteristic of it that would allow a simpler way to implement it. But
            without that information from you, we're stuck.

            Pete

            Comment

            • Tem

              #7
              Re: Down casting objects

              I thought that would make the problem easier to understand...

              It's a chemistry problem
              elements
              Li, Na, K, Rb, Cs, Fr
              all implement interface IAlkaliMetal.

              Public Void PrepareCombine( IAlkaliMetal elem1, IAlkaliMetal elem2)
              {
              if(elem1is Li && elem2 is Li)
              Combine(((Li)el em1),((Na)elem2 );
              else if(elem1is Li && elem2 is Na)
              Combine(((Li)el em1),((Na)elem2 );
              else if(elem1is Li && elem2 is K)
              Combine(((Li)el em1),((K)elem2) ;...
              }

              This is to illustrate what im trying to do, they don't really combine this
              way.
              Combine method for each possible input types.
              Public Void Combine(Li elem1, Li elem2){....}
              Public Void Combine(Li elem1, Na elem2){....}
              Public Void Combine(Li elem1, K elem2){....}

              so again my question is there a way to design this so i so have to use all
              those if else if statement and go directly to the corresponding Combine
              method
              If there are three inputs then there would be 216.

              Ideally, it would just know which overload method to go to.
              Public Void PrepareCombine( IAlkaliMetal elem1, IAlkaliMetal elem2)
              {
              Combine(elem1,e lem2);
              }

              Is there a better way to design this?

              Tem
              "Peter Duniho" <NpOeStPeAdM@nn owslpianmk.comw rote in message
              news:op.t9oqmnf h8jd0ej@petes-computer.local. ..
              On Tue, 15 Apr 2008 19:00:45 -0700, Tem <tem1232@yahoo. comwrote:
              >
              >[...]
              >I have 36 possibilities, if and else if becomes very messy and lots of
              >room for making errors.
              >Im not sure how to use the method you mentioned with more than 1
              >parameter.
              >
              It would really help if you could explain what it is exactly you're
              doing. Do you literally have 36 different methods that will be called?
              >
              It's possible that the problem can be factored down to something that's
              simpler. But if all we know about the problem is that you have 36
              different possible outcomes, dependent on two different variables, it's
              difficult to see how you'd make it simpler than a straight enumeration of
              the possibilities.
              >
              If we knew more about the problem, it's likely that there's some
              characteristic of it that would allow a simpler way to implement it. But
              without that information from you, we're stuck.
              >
              Pete

              Comment

              • Peter Duniho

                #8
                Re: Down casting objects

                On Wed, 16 Apr 2008 01:29:11 -0700, Tem <tem1232@yahoo. comwrote:
                I thought that would make the problem easier to understand...
                >
                It's a chemistry problem
                elements
                Li, Na, K, Rb, Cs, Fr
                all implement interface IAlkaliMetal.
                I don't understand this example:
                Public Void PrepareCombine( IAlkaliMetal elem1, IAlkaliMetal elem2)
                {
                if(elem1is Li && elem2 is Li)
                Combine(((Li)el em1),((Na)elem2 );
                If elem2 is Li, why are you casting to Na?

                It's well and good to simplify your code examples, but you still need to
                make sure that they are correct and compilable. I will assume that you
                simply meant to write Li instead of Na here, and that you didn't intend to
                leave off the required paren at the end of each method call in your
                example.

                That said, you still haven't really explained what these methods do. If
                each possible combination really represents some different operation, then
                I don't see any way out of at some point having to channel the flow of
                execution down to one of those possible operations. If the operations are
                specific to the combinations of the elements, then you will at some point
                need some kind of comparison to resolve the combinations into individual
                operations.

                It's possible that you could represent these combinations in a table, with
                delegates representing each method that handles the combination. Then
                rather than having a bunch of if/else if statements, you could search the
                table for the combination in question.

                As far as extending this to combinations of three, again...what does this
                operation do? With 216 combinations, do you really have 216 different
                methods you might call?

                Frankly, you haven't really clarified the problem. Your new example is
                really pretty much the same as your original, except with different
                names. It doesn't address the kinds of clarifications I was asking for.

                Pete

                Comment

                • Jeff Louie

                  #9
                  Re: Down casting objects

                  Off the top of my pointed head. Each AlkaliMetal _could_ implement
                  IAlkiliMetal.Co mbine as an instance method
                  someAlkaliMetal .Combine(someAl kiliMetal). So a particular metal would
                  presumably know how to combine with any other metal including itself.

                  The static method CombineAlkiliMe tals(someAlkili Metal,someAlkil iMetal)
                  could
                  simply checks for null parameters and then calls the appropriate
                  instance
                  method someAlkiliMetal .Combine. I can see a downside in duplication of
                  code
                  for am1.Combine(am2 ) and am2.Combine(am1 ), which, presumably, would have
                  the same implementation.

                  Regards,
                  Jeff

                  *** Sent via Developersdex http://www.developersdex.com ***

                  Comment

                  • Peter Duniho

                    #10
                    Re: Down casting objects

                    On Wed, 16 Apr 2008 19:34:25 -0700, Jeff Louie <anonymous@devd ex.com>
                    wrote:
                    Off the top of my pointed head. Each AlkaliMetal _could_ implement
                    IAlkiliMetal.Co mbine as an instance method
                    someAlkaliMetal .Combine(someAl kiliMetal). So a particular metal would
                    presumably know how to combine with any other metal including itself.
                    But would still have to check the type of the passed in object. Making it
                    an instance method might help with respect to breaking the problem down
                    into smaller, easier-to-manage parts. But it wouldn't reduce the total
                    number of type checks.

                    There's also a potential issue with respect to the three-parameter
                    scenario, but without more details from the OP, it's hard to know for
                    sure, since we don't know how the three-parameter scenario differs from
                    the two-parameter scenario (i.e. is it completely different, or does the
                    three-parameter scenario somehow resolve down to pairs of the
                    two-parameter scenario).

                    Hopefully the OP will provide some additional details that actually do
                    elaborate on the problem. :)

                    Pete

                    Comment

                    • Jeff Louie

                      #11
                      Re: Down casting objects

                      Hi Peter.. I agree it is difficult to solve a puzzle without all the
                      pieces.

                      For n metals, it _might_ be possible to SWITCH on the SUM OF ATOMIC
                      NUMBERS especially if this results in no mathematical duplicates for a
                      given
                      combination of n metals of atomic numbers in the domain of
                      {1,3,11,19,37,5 5,87}. So IAlkaliMetal inherits from IElement and:

                      int IElement.GetAto micNumber() as readonly property.

                      Regards,
                      Jeff

                      *** Sent via Developersdex http://www.developersdex.com ***

                      Comment

                      • Peter Duniho

                        #12
                        Re: Down casting objects

                        On Wed, 16 Apr 2008 21:05:41 -0700, Jeff Louie <anonymous@devd ex.com
                        wrote:
                        Hi Peter.. I agree it is difficult to solve a puzzle without all the
                        pieces.
                        >
                        For n metals, it _might_ be possible to SWITCH on the SUM OF ATOMIC
                        NUMBERS especially if this results in no mathematical duplicates for a
                        given
                        combination of n metals of atomic numbers in the domain of
                        {1,3,11,19,37,5 5,87}. So IAlkaliMetal inherits from IElement and:
                        >
                        int IElement.GetAto micNumber() as readonly property.
                        Heh. Well, you're on the right track. :)

                        I wouldn't bother with using the actual atomic number though. In spite of
                        the name, we're really just talking about C# classes here. :) It would
                        be simple enough to define a "flags" enumeration where each member of the
                        enumeration corresponds to one of the classes/elements.

                        Then the readonly property you suggest would just return that, and you'd
                        switch on the combination of two or more of the flags:

                        [Flags]
                        enum MetalID
                        {
                        Li = 1, Na = 2, K = 4, Rb = 8, Cs = 16, Fr = 32
                        }

                        class Li : IAlkaliMetal
                        {
                        public MetalID MetalID { get { return MetalID.Li; } }
                        }

                        // etc.

                        void Combine(IAlkali Metal metal1, IAlkaliMetal metal2)
                        {
                        switch (metal1.MetalID | metal2.MetalID)
                        {
                        case (MetalID.Li | MetalID.Li):
                        CombineLiAndLi( metal1, metal2);
                        break;
                        case (MetalID.Li | MetalID.Na):
                        CombineLiAndNa( metal1, metal2);
                        break;
                        // etc.
                        }
                        }

                        It's not really less typing, but it's perhaps more representationa l of
                        what's going on, and should be at least somewhat computationally more
                        efficient.

                        Of course, this is fun, but until we get more details who knows whether
                        it's really a useful approach. :)

                        Pete

                        Comment

                        • Tem

                          #13
                          Re: Down casting objects

                          >if(elem1is Li && elem2 is Li)
                          > Combine(((Li)el em1),((Na)elem2 );
                          >
                          If elem2 is Li, why are you casting to Na?
                          That's a typo. sorry. should be Combine(((Li)el em1),((Li)elem2 );
                          >
                          It's well and good to simplify your code examples, but you still need to
                          make sure that they are correct and compilable. I will assume that you
                          simply meant to write Li instead of Na here, and that you didn't intend
                          to leave off the required paren at the end of each method call in your
                          example.
                          sorry. typo.
                          >
                          That said, you still haven't really explained what these methods do. If
                          each possible combination really represents some different operation,
                          then I don't see any way out of at some point having to channel the flow
                          of execution down to one of those possible operations. If the
                          operations are specific to the combinations of the elements, then you
                          will at some point need some kind of comparison to resolve the
                          combinations into individual operations.
                          I haven't figured out what each Combine method will do. That's going to
                          be my next task. But I do want to structure my program correctly so that
                          I can add more code easily later and keep good maintainability .

                          The method Combine will perform totally different operations depending
                          on input type.
                          >
                          It's possible that you could represent these combinations in a table,
                          with delegates representing each method that handles the combination.
                          Then rather than having a bunch of if/else if statements, you could
                          search the table for the combination in question.
                          This sounds like a possible solution. Not sure how I would construct
                          such table and how to use delegates.
                          >
                          As far as extending this to combinations of three, again...what does
                          this operation do? With 216 combinations, do you really have 216
                          different methods you might call?
                          Yes with three inputs there will be 216 unique methods.

                          Thank you.


                          Comment

                          • Tem

                            #14
                            Re: Down casting objects

                            I thought of this as a possible solution but

                            someAlkaliMetal 1.Combine(someA lkiliMetal2)

                            The Combine method in instance someAlkaliMetal 1 would still need to
                            check the type of someAlkiliMetal 2

                            Off the top of my pointed head. Each AlkaliMetal _could_ implement
                            IAlkiliMetal.Co mbine as an instance method
                            someAlkaliMetal .Combine(someAl kiliMetal). So a particular metal would
                            presumably know how to combine with any other metal including itself.
                            >
                            The static method CombineAlkiliMe tals(someAlkili Metal,someAlkil iMetal)
                            could
                            simply checks for null parameters and then calls the appropriate
                            instance
                            method someAlkiliMetal .Combine. I can see a downside in duplication of
                            code
                            for am1.Combine(am2 ) and am2.Combine(am1 ), which, presumably, would have
                            the same implementation.
                            >
                            Regards,
                            Jeff
                            >
                            *** Sent via Developersdex http://www.developersdex.com ***

                            Comment

                            • Tem

                              #15
                              Re: Down casting objects

                              I was just think the same.

                              This is what a 3 input parameter scenario would look like, again, each
                              Combine method does different things

                              Public Void PrepareCombine( IAlkaliMetal elem1, IAlkaliMetal elem2,
                              AlkaliMetal elem3)
                              {
                              if(elem1 is Li && elem2 is Li && elem3 is Li)
                              Combine(((Li)el em1),((Li)elem2 ),((Li)elem3));
                              else if(elem1 is Li && elem2 is Li && elem3 is Na)
                              Combine(((Li)el em1),((Li)elem2 ),((Li)elem3));
                              else if(elem1 is Li && elem2 is Li && elem3 is K)
                              Combine(((Li)el em1),((Li)elem2 ), ((K)elem3));...
                              }


                              Peter Duniho wrote:
                              On Wed, 16 Apr 2008 19:34:25 -0700, Jeff Louie <anonymous@devd ex.com>
                              wrote:
                              >
                              >Off the top of my pointed head. Each AlkaliMetal _could_ implement
                              >IAlkiliMetal.C ombine as an instance method
                              >someAlkaliMeta l.Combine(someA lkiliMetal). So a particular metal would
                              >presumably know how to combine with any other metal including itself.
                              >
                              But would still have to check the type of the passed in object. Making
                              it an instance method might help with respect to breaking the problem
                              down into smaller, easier-to-manage parts. But it wouldn't reduce the
                              total number of type checks.
                              >
                              There's also a potential issue with respect to the three-parameter
                              scenario, but without more details from the OP, it's hard to know for
                              sure, since we don't know how the three-parameter scenario differs from
                              the two-parameter scenario (i.e. is it completely different, or does the
                              three-parameter scenario somehow resolve down to pairs of the
                              two-parameter scenario).
                              >
                              Hopefully the OP will provide some additional details that actually do
                              elaborate on the problem. :)
                              >
                              Pete

                              Comment

                              Working...