when casting, receiving: System.InvalidCastException (Specified cast is not valid)

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

    when casting, receiving: System.InvalidCastException (Specified cast is not valid)

    I'm trying to inherit subclass from System.Diagnost ics.Process, but
    whenever I cast a "Process" object to it's subclass, I encounter an
    exception "System.Invalid CastException" ("Specified cast is not
    valid"). How do I fix it ?

    using System.Diagnost ics;
    ..
    ..
    class NewProcess: Process
    {
    public override String ToString()
    {
    return this.ProcessNam e;
    }
    }
    ..
    ..
    Process p, n;
    p = new Process;
    DoSomethingOnPr ocess (p);
    n = (NewProcess) p; // throws System.InvalidC astException:
    Specified cast is not valid
    ..
    ..
    ..
    Thank you in advance, for any help.

  • Bruce Wood

    #2
    Re: when casting, receiving: System.InvalidC astException (Specified cast is not valid)


    Gamma wrote:
    I'm trying to inherit subclass from System.Diagnost ics.Process, but
    whenever I cast a "Process" object to it's subclass, I encounter an
    exception "System.Invalid CastException" ("Specified cast is not
    valid"). How do I fix it ?
    >
    using System.Diagnost ics;
    .
    .
    class NewProcess: Process
    {
    public override String ToString()
    {
    return this.ProcessNam e;
    }
    }
    .
    .
    Process p, n;
    p = new Process;
    DoSomethingOnPr ocess (p);
    n = (NewProcess) p; // throws System.InvalidC astException:
    Specified cast is not valid
    Yes, it would throw an InvalidCastExce ption. You cannot cast a base
    class object to a derived class reference, only the other way around.
    The object to which p refers is a Process, not a NewProcess. Besides,
    the cast is useless because n is a reference to a Process, too.

    Perhaps you misunderstand the difference between object (instance) type
    and reference type, and perhaps also some things about how inheritance
    works?

    What do you think should be happening in the code you wrote? That will
    help me explain it better.

    Comment

    • sloan

      #3
      Re: when casting, receiving: System.InvalidC astException (Specified cast is not valid)

      What error you're getting is correct.

      This should work..........a nd show the subtle difference.

      Process p, n;
      p = new NewProcess();
      DoSomethingOnPr ocess (p);
      n = (NewProcess) p;





      "Gamma" <TalGamma@gmail .comwrote in message
      news:1160583163 .466334.118300@ h48g2000cwc.goo glegroups.com.. .
      I'm trying to inherit subclass from System.Diagnost ics.Process, but
      whenever I cast a "Process" object to it's subclass, I encounter an
      exception "System.Invalid CastException" ("Specified cast is not
      valid"). How do I fix it ?
      >
      using System.Diagnost ics;
      .
      .
      class NewProcess: Process
      {
      public override String ToString()
      {
      return this.ProcessNam e;
      }
      }
      .
      .
      Process p, n;
      p = new Process;
      DoSomethingOnPr ocess (p);
      n = (NewProcess) p; // throws System.InvalidC astException:
      Specified cast is not valid
      .
      .
      .
      Thank you in advance, for any help.
      >

      Comment

      • Gamma

        #4
        Re: when casting, receiving: System.InvalidC astException (Specified cast is not valid)

        Thank you for your help.

        1. What I want to do is this: I have an array of processes, and I want
        to put them in a listbox. Since the listbox uses the "ToString" method
        to display the process's name, and since the "ToString" method of the
        Process's class (System.Diagnos tics.Process) returns the class's name
        besides the name of the process (which is redundant information), I
        inherited a class NewProcess that overrides only the "ToString" method.

        2. My roots are C++, and in C++, if I have a class that inherits from
        another class and overrides a method, the correct way to use it is in
        the following way (C++ code):

        Process *p,*n;
        p = new Process;
        DoSomething(p);
        n = (MyProcess*)p;

        while trying to learn C#, I used that same technique, but obviously not
        successfully. Therefore, what I want to understand is this: I have a
        Process object (which is a given situation), and I want to
        polymorphically use it as my derived class (to force it to treat it's
        data the way I want it to).

        Comment

        • Martin Z

          #5
          Re: when casting, receiving: System.InvalidC astException (Specified cast is not valid)

          No offense, but that is bad C++ - Unsafe use of the leaky "new"
          operator, use of deprecated C-style typecasting, and you're using a
          subclass as a decorator for an existing object. Subclasses are new
          types whose objects happen to be useable in the place of their
          superclass objects - not ways to override old behaviour of an old
          object.

          What you want to do (in C++ or C) is wrap the old objects in a new
          object, or else change the called method to use your subclass. The
          general guideline in a generic-supporting language (C# 2.0 or C++) is
          that casting is a design smell.

          Create a wrapper like


          public class MyProcessWrappe r
          {
          private Process _process;
          public MyProcessWrappe r(Process process)
          {
          this._process = process;
          }

          public Override string ToString()
          {
          return "My New ToString Crap";
          }
          }


          and then use

          myList.Add(MyPr ocessWrapper(ol dProcess));

          If you need to get the process back out of the wrapper, you can make
          the field public or put it in a property or something (property if this
          is production code, pubclic field if this is your own tinkering).


          Gamma wrote:
          Thank you for your help.
          >
          1. What I want to do is this: I have an array of processes, and I want
          to put them in a listbox. Since the listbox uses the "ToString" method
          to display the process's name, and since the "ToString" method of the
          Process's class (System.Diagnos tics.Process) returns the class's name
          besides the name of the process (which is redundant information), I
          inherited a class NewProcess that overrides only the "ToString" method.
          >
          2. My roots are C++, and in C++, if I have a class that inherits from
          another class and overrides a method, the correct way to use it is in
          the following way (C++ code):
          >
          Process *p,*n;
          p = new Process;
          DoSomething(p);
          n = (MyProcess*)p;
          >
          while trying to learn C#, I used that same technique, but obviously not
          successfully. Therefore, what I want to understand is this: I have a
          Process object (which is a given situation), and I want to
          polymorphically use it as my derived class (to force it to treat it's
          data the way I want it to).

          Comment

          • sloan

            #6
            Re: when casting, receiving: System.InvalidC astException (Specified cast is not valid)

            Martin is ( I think) the Proxy design pattern:

            Learn how to use the C# Proxy design pattern to control access to objects and add additional functionality, with quick and easy examples. 100% Source code.





            "Gamma" <TalGamma@gmail .comwrote in message
            news:1160598627 .858626.177320@ h48g2000cwc.goo glegroups.com.. .
            Thank you for your help.
            >
            1. What I want to do is this: I have an array of processes, and I want
            to put them in a listbox. Since the listbox uses the "ToString" method
            to display the process's name, and since the "ToString" method of the
            Process's class (System.Diagnos tics.Process) returns the class's name
            besides the name of the process (which is redundant information), I
            inherited a class NewProcess that overrides only the "ToString" method.
            >
            2. My roots are C++, and in C++, if I have a class that inherits from
            another class and overrides a method, the correct way to use it is in
            the following way (C++ code):
            >
            Process *p,*n;
            p = new Process;
            DoSomething(p);
            n = (MyProcess*)p;
            >
            while trying to learn C#, I used that same technique, but obviously not
            successfully. Therefore, what I want to understand is this: I have a
            Process object (which is a given situation), and I want to
            polymorphically use it as my derived class (to force it to treat it's
            data the way I want it to).
            >

            Comment

            • Peter Duniho

              #7
              Re: when casting, receiving: System.InvalidC astException (Specified cast is not valid)

              "Gamma" <TalGamma@gmail .comwrote in message
              news:1160598627 .858626.177320@ h48g2000cwc.goo glegroups.com.. .
              Thank you for your help.
              >
              1. What I want to do is this: I have an array of processes, and I want
              to put them in a listbox. Since the listbox uses the "ToString" method
              to display the process's name, and since the "ToString" method of the
              Process's class (System.Diagnos tics.Process) returns the class's name
              besides the name of the process (which is redundant information), I
              inherited a class NewProcess that overrides only the "ToString" method.
              Then you need to actually create instances of NewProcess, not instances of
              Process. If you are not creating the instances of the Process yourself, you
              will need to wrap them as Martin suggests, since you can't go back and
              change something created as a Process into a NewProcess.

              If you ARE creating the instances, then the change sloan offered will work
              fine. In that case, you can ensure that the instance created is of the
              derived class you've defined, rather than the base class, and the override
              will work just fine.
              2. My roots are C++, and in C++, if I have a class that inherits from
              another class and overrides a method, the correct way to use it is in
              the following way (C++ code):
              >
              Process *p,*n;
              p = new Process;
              DoSomething(p);
              n = (MyProcess*)p;
              >
              while trying to learn C#, I used that same technique, but obviously not
              successfully.
              I agree with Martin. It's true that a C++ compiler will let you do this.
              But that doesn't make it correct code (and if you did a C++ safe typecast
              like that, it would fail), nor does it do what you seem to think it does.

              A true "override" of behavior involves virtual functions in C++. Without a
              virtual function, the behavior is defined only by the type the pointer is
              currently treated as.

              For example:

              class A
              {
              public:
              int Value { return 5; }
              }

              class B : public A
              {
              public:
              int Value { return 10; }
              }

              If you have this code:

              A *a1, *a2;
              B *b1;
              a1 = new A();
              a2 = (B *)a1;
              b1 = (B *)a1;

              Then a1->Value() returns 5. a2->Value() *also* returns 5. The statement
              b1->Value() returns 10, but only because you're calling the function
              B::Value explicitly. It has nothing to do with the actual instance a1 and
              if you cast b1 back to a pointer to an A, you are back to the call to
              Value() returning 5.

              If all you're inheriting the class for is to return a different value when
              you explicitly call B::Value(), you might as well skip the inheritance and
              just hard-code your constant instead where it would have been used.

              More commonly, when one talks about an "override", they mean that the class
              will retain the overridden behavior even when the class is only known to be
              a parent class. For example:

              class A
              {
              public:
              virtual int Value { return 5; }
              }

              class B : public A
              {
              public:
              virtual int Value { return 10; }
              }

              In this case, if you have this code:

              A *a1;
              B *b1;

              a1 = new A();
              b1 = (B *) a1;
              b1 = new B();
              a1 = (A *) b1;

              After the first two lines have executed, a1->Value() would return 5, as
              would b1->Value(). After the third line has executed, b1->Value() would
              return 10, and after the fourth line executes, a1->Value() would also return
              10.

              In other words, in this second example the value returned depends not on the
              type of the variable, but on the type used when creating the instance of the
              class.

              Note that in both examples, casting something created as an A to a pointer
              to a B is *illegal*. It doesn't harm anything in this case (as in the
              second line of code executed), because no attempt is made to access
              something that was defined only in the B class. But if the B class included
              some member variable or a virtual function, either of which didn't exist in
              the A class, you would get an error trying to access that part of the B
              class through a pointer caSt from an instance of an A class (the exact error
              would vary...it could just be simply the wrong data, or the program could
              crash, depending on what you tried to access and where the object was in
              memory).

              In other words, the code you posted is really dangerous, and doesn't at all
              do what you want. It didn't work in C++ and it doesn't work in C#.
              Thankfully, C# is better about protecting you, and thus generates the error
              you're getting.
              Therefore, what I want to understand is this: I have a
              Process object (which is a given situation), and I want to
              polymorphically use it as my derived class (to force it to treat it's
              data the way I want it to).
              You can't force something that's not already a NewProcess to act as if it is
              a NewProcess.

              Pete


              Comment

              • Gamma

                #8
                Re: when casting, receiving: System.InvalidC astException (Specified cast is not valid)

                Thank you all for your explanations, they were focused and profound. I
                understand now my mistakes, and that the correct way to do what I want
                is indeed by a wrapper class.

                Comment

                • Peter Duniho

                  #9
                  Re: when casting, receiving: System.InvalidC astException (Specified cast is not valid)

                  "Gamma" <TalGamma@gmail .comwrote in message
                  news:1160647608 .407565.258280@ e3g2000cwe.goog legroups.com...
                  Thank you all for your explanations, they were focused and profound. I
                  understand now my mistakes, and that the correct way to do what I want
                  is indeed by a wrapper class.
                  You're welcome. I happy you found the various replies helpful!


                  Comment

                  Working...