473,407 Members | 2,326 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

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

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

using System.Diagnostics;
..
..
class NewProcess: Process
{
public override String ToString()
{
return this.ProcessName;
}
}
..
..
Process p, n;
p = new Process;
DoSomethingOnProcess (p);
n = (NewProcess) p; // throws System.InvalidCastException:
Specified cast is not valid
..
..
..
Thank you in advance, for any help.

Oct 11 '06 #1
8 4238

Gamma wrote:
I'm trying to inherit subclass from System.Diagnostics.Process, but
whenever I cast a "Process" object to it's subclass, I encounter an
exception "System.InvalidCastException" ("Specified cast is not
valid"). How do I fix it ?

using System.Diagnostics;
.
.
class NewProcess: Process
{
public override String ToString()
{
return this.ProcessName;
}
}
.
.
Process p, n;
p = new Process;
DoSomethingOnProcess (p);
n = (NewProcess) p; // throws System.InvalidCastException:
Specified cast is not valid
Yes, it would throw an InvalidCastException. 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.

Oct 11 '06 #2
What error you're getting is correct.

This should work..........and show the subtle difference.

Process p, n;
p = new NewProcess();
DoSomethingOnProcess (p);
n = (NewProcess) p;

"Gamma" <Ta******@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com...
I'm trying to inherit subclass from System.Diagnostics.Process, but
whenever I cast a "Process" object to it's subclass, I encounter an
exception "System.InvalidCastException" ("Specified cast is not
valid"). How do I fix it ?

using System.Diagnostics;
.
.
class NewProcess: Process
{
public override String ToString()
{
return this.ProcessName;
}
}
.
.
Process p, n;
p = new Process;
DoSomethingOnProcess (p);
n = (NewProcess) p; // throws System.InvalidCastException:
Specified cast is not valid
.
.
.
Thank you in advance, for any help.

Oct 11 '06 #3
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.Diagnostics.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).

Oct 11 '06 #4
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 MyProcessWrapper
{
private Process _process;
public MyProcessWrapper(Process process)
{
this._process = process;
}

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

myList.Add(MyProcessWrapper(oldProcess));

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.Diagnostics.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).
Oct 11 '06 #5
Martin is ( I think) the Proxy design pattern:

http://www.dofactory.com/Patterns/PatternProxy.aspx


"Gamma" <Ta******@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.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.Diagnostics.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).

Oct 11 '06 #6
"Gamma" <Ta******@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.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.Diagnostics.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
Oct 11 '06 #7
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.

Oct 12 '06 #8
"Gamma" <Ta******@gmail.comwrote in message
news:11**********************@e3g2000cwe.googlegro ups.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!
Oct 13 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Miguel Angel Dinelli | last post by:
I´m trying to execute a project and I get this error System.InvalidCastException: Specified cast is not valid. I found in microsoft some Q in 327287, but I not sure how make to solution it. ...
11
by: Roy Lawson | last post by:
I have no idea what is going on here. I wrote a simple application in VB.NET to generate a Crystal Report, and I am now trying to move it to ASP.NET with Crstal Enterprise. I wish I could tell...
6
by: Biva | last post by:
Hello All, Please help. I get the following error from my webpage: System.InvalidCastException: Specified cast is not valid. at Time.MaintAtRiskProjects.UpdateProject(String Project, String...
0
by: QA | last post by:
I am using a Business Scorecard Accelarator in a Sharepoint Portal 2003 using SQL Server 2005 I am getting the following error: Error,5/7/2005 10:50:14 AM,580,AUE1\Administrator,"Specified cast is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.