472,783 Members | 981 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,783 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 4172

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:
Im 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...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{

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.