Debug this if you can.

G

GeezerButler

I have a class A derived from interface B.
I create object of A (using reflection) and then i try to cast the
object A to type B,

object objA = MyReflectionFunction("classA");
B objB = (B) objA; //Exception thrown here

I get Invalid cast exception.

Now the funnier part is that before/after the offending line is
executed, if i copy
B objB = (B) objA;
to the immediate window is VS2005, then it gets executed without a
problem.

This has me stumped now for the last few hours.

Can you help in any way.
Thanks!
 
G

GeezerButler

I have a class A derived from interface B.
I create object of A (using reflection) and then i try to cast the
object A to type B,

object objA = MyReflectionFunction("classA");
B objB = (B) objA; //Exception thrown here

I get Invalid cast exception.

Now the funnier part is that before/after the offending line is
executed, if i copy
B objB = (B) objA;
to the immediate window is VS2005, then it gets executed without a
problem.

This has me stumped now for the last few hours.

Can you help in any way.
Thanks!

Forget the interface, i cant even get this to work.

object objA = MyReflectionFunction("classA");
if (!objA .GetType().Equals(typeof(A)))
{
throw new Exception("wrong type"); //throws exception here
}
Seems like the objA is not of type A, so i printed out all the public
properties of the types and all of them are same.
I can't see why the types are different.
Is there some way to know what exactly is causing the
InvalidCastException?

I'm totally foxed now :(
 
P

Peter Duniho

I have a class A derived from interface B.
I create object of A (using reflection) and then i try to cast the
object A to type B,

object objA = MyReflectionFunction("classA");
B objB = (B) objA; //Exception thrown here

I get Invalid cast exception.

[...]
This has me stumped now for the last few hours.

It seems to me that you've left out the very most important elements of
your question. In particular, you have not included the definition of
"MyReflectionFunction", nor of class A and interface B.

The code that fails isn't particular interesting without those.

Pete
 
G

GeezerButler

I have a class A derived from interface B.
I create object of A (using reflection) and then i try to cast the
object A to type B,
object objA = MyReflectionFunction("classA");
B objB = (B) objA; //Exception thrown here
I get Invalid cast exception.
[...]
This has me stumped now for the last few hours.

It seems to me that you've left out the very most important elements of
your question. In particular, you have not included the definition of
"MyReflectionFunction", nor of class A and interface B.

The code that fails isn't particular interesting without those.

Pete

Well MyReflectionFunction is not really mine. It's a third party dll
which i have used many times before on really large and complex
classes and it is safe to assume that it works fine.

I removed each and every member variable of class A but i still get
the error.
" Unable to cast object of type 'MyNamespace.A' to 'MyNamespace.A' "

Code i am trying now:
object obj = MyReflectionFunction("classA");
A objA = (A) obj; //Exception thrown here

What amzes me is that when I copy paste this "(A) obj" in QuickWatch
or in Immediate window, the casting works!

public interface B
{
string Parse(string text);
}

public class A: B
{
public A() {}
public string Parse(string text) {return null;}
}

Gah! This is so freaky.
 
G

GeezerButler

I have a class A derived from interface B.
I create object of A (using reflection) and then i try to cast the
object A to type B,
object objA = MyReflectionFunction("classA");
B objB = (B) objA; //Exception thrown here
I get Invalid cast exception.
[...]
This has me stumped now for the last few hours.
It seems to me that you've left out the very most important elements of
your question. In particular, you have not included the definition of
"MyReflectionFunction", nor of class A and interface B.
The code that fails isn't particular interesting without those.

Well MyReflectionFunction is not really mine. It's a third party dll
which i have used many times before on really large and complex
classes and it is safe to assume that it works fine.

I removed each and every member variable of class A but i still get
the error.
" Unable to cast object of type 'MyNamespace.A' to 'MyNamespace.A' "

Code i am trying now:
object obj = MyReflectionFunction("classA");
A objA = (A) obj; //Exception thrown here

What amzes me is that when I copy paste this "(A) obj" in QuickWatch
or in Immediate window, the casting works!

public interface B
{
string Parse(string text);

}

public class A: B
{
public A() {}
public string Parse(string text) {return null;}

}

Gah! This is so freaky.- Hide quoted text -

- Show quoted text -

And here's the disassembly of this line (A objA = (A) obj): Sadly i
dont know what to make of it.
Exception is thrown at 000001be:

000001a0 cmp dword ptr [ebp-50h],0
000001a4 je 000001C5
000001a6 mov eax,dword ptr [ebp-50h]
000001a9 cmp dword ptr [eax],3BB28C0h
000001af jne 000001B6
000001b1 mov eax,dword ptr [ebp-50h]
000001b4 jmp 000001C3
000001b6 mov edx,dword ptr [ebp-50h]
000001b9 mov ecx,3BB28C0h
000001be call 791893A4
000001c3 jmp 000001C8
000001c5 mov eax,dword ptr [ebp-50h]
000001c8 mov dword ptr [ebp-54h],eax
 
P

Peter Duniho

Well MyReflectionFunction is not really mine. It's a third party dll
which i have used many times before on really large and complex
classes and it is safe to assume that it works fine.

I disagree. It seems to me that in fact, it does not work and that's the
crux of your problem. Surely the fact that you get an exception trying to
use an object the function returns is a clear signal that it is NOT safe
to assume that it works fine.

If the object returned by the function were really of class "A", you would
not get an exception casting it.

I don't have a good explanation for why the debugger doesn't complain, but
I do note that at least in some cases, the debugger will happily cast
whatever you give it to whatever you want. I can't say I've ever seen
this in the case of class instances -- seems like it's more a value-type
sort of thing -- but just because the debugger doesn't complain doesn't
tell me that all is well with your class instance.

If I had to guess, I'd guess that you somehow have two different class
"A"s running around. I cannot fathom why this could be, but it's possible
that there's something funny going on in the MyReflectionFunction() that
causes that to happen. But again, without that code, it's not possible to
comment on it.

There is a very small chance that someone else will take a look at this
and identify the behavior and explain what's wrong. However, I think you
are much more likely to get help if you can post a concise-but-complete
code sample that demonstrates the problem.

Pete
 
P

Peter Duniho

And here's the disassembly of this line (A objA = (A) obj): Sadly i
dont know what to make of it.

Well, there's not much to make of it. It's the same exact code you'd see
casting any reference type to any other reference type.

The code first checks for a null pointer. Null pointers can be cast to
anything, so if it's null, it skips right ahead to offset 0x01c5 where the
local variable gets copied to the other local variable.

If the pointer isn't null, then it compares the signature value of the
instance to the constant 0x3BB28C0. If they are not equal, it jumps to
the section of the code that throws the exception. If they are equal, it
copies the local variable to the eax register, then does a double-jump
eventually winding up at the last line where the eax register is copied to
the other local variable.

(Note that the double-jump is likely because you're showing non-optimized
code. Easier to read, but it includes funny things like that, that are a
side-effect of the compiler allowing for more complex expressions).

The bottom line here is that there's absolutely nothing odd about the code
you've posted. The compiler is doing exactly what you'd expect, and so
for the exception to be thrown, there has to be something wrong with the
instance the object variable references. And the only way for that to
happen is for the MyReflectionFunction() to have a problem in it.

Pete

Exception is thrown at 000001be:

000001a0 cmp dword ptr [ebp-50h],0
000001a4 je 000001C5
000001a6 mov eax,dword ptr [ebp-50h]
000001a9 cmp dword ptr [eax],3BB28C0h
000001af jne 000001B6
000001b1 mov eax,dword ptr [ebp-50h]
000001b4 jmp 000001C3
000001b6 mov edx,dword ptr [ebp-50h]
000001b9 mov ecx,3BB28C0h
000001be call 791893A4
000001c3 jmp 000001C8
000001c5 mov eax,dword ptr [ebp-50h]
000001c8 mov dword ptr [ebp-54h],eax
 
J

Jon Skeet [C# MVP]

GeezerButler said:
I have a class A derived from interface B.
I create object of A (using reflection) and then i try to cast the
object A to type B,

object objA = MyReflectionFunction("classA");
B objB = (B) objA; //Exception thrown here

I get Invalid cast exception.

Now the funnier part is that before/after the offending line is
executed, if i copy
B objB = (B) objA;
to the immediate window is VS2005, then it gets executed without a
problem.

This has me stumped now for the last few hours.

Do you by any chance have B defined in multiple assemblies? If so, that
would certainly explain things somewhat.
 
G

GeezerButler

Do you by any chance have B defined in multiple assemblies? If so, that
would certainly explain things somewhat.

--
Jon Skeet - <[email protected]>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too- Hide quoted text -

- Show quoted text -


Now i only have the class A. No interface B.
public class A
{
//Completely empty
}

The myReflectedFunction works like this:
1. There is an xml like this:
<namespace name="MyNamespace.A">
<property name="type_name">
<value>MyNamespace.A</value>
</property>
<property name="assembly">
<value>..path till my project\bin\Debug\MyNamespace.dll</value>
</property>
</namespace>
2. I call object a = myReflectedFunction("MyNamespace.A");
This reads the type and assembly from the xml above and creates the
object as follows
3. The code for creating the object is like this:
Type type = Assembly.LoadFrom(assemblyName,
securityAttributes).GetType(typeName, true, ignoreCase);
object obj = type.GetConstructor(bindingAttr, binder,
callConvention, types, modifiers).
Invoke(bindingAttr, binder, parameters, culture);
return obj;

When i view the type and obj in the debugger, i can see that the type
is correct and the object is of correct type. Atleast it seems to me
that they are correct.
Infact in the step 3 mentioned above, i can debug into the ctor of A.
So i can be sure that it's class A's ctor that is being called and not
some other class with the same name.

So after object a = myReflectedFunction("MyNamespace.A");
this line
a.GetType().Equals(typeof(MyNamespace.A)
returns false!!
Any idea as to how i can see why the above line returns false?
 
G

GeezerButler

Now i only have the class A. No interface B.
public class A
{
//Completely empty

}

The myReflectedFunction works like this:
1. There is an xml like this:
<namespace name="MyNamespace.A">
<property name="type_name">
<value>MyNamespace.A</value>
</property>
<property name="assembly">
<value>..path till my project\bin\Debug\MyNamespace.dll</value>
</property>
</namespace>
2. I call object a = myReflectedFunction("MyNamespace.A");
This reads the type and assembly from the xml above and creates the
object as follows
3. The code for creating the object is like this:
Type type = Assembly.LoadFrom(assemblyName,
securityAttributes).GetType(typeName, true, ignoreCase);
object obj = type.GetConstructor(bindingAttr, binder,
callConvention, types, modifiers).
Invoke(bindingAttr, binder, parameters, culture);
return obj;

When i view the type and obj in the debugger, i can see that the type
is correct and the object is of correct type. Atleast it seems to me
that they are correct.
Infact in the step 3 mentioned above, i can debug into the ctor of A.
So i can be sure that it's class A's ctor that is being called and not
some other class with the same name.

So after object a = myReflectedFunction("MyNamespace.A");
this line
a.GetType().Equals(typeof(MyNamespace.A)
returns false!!
Any idea as to how i can see why the above line returns false?- Hide quoted text -

- Show quoted text -

One correction above, ClassA is not totally empty but has a default
ctor, which i think is as good is empty right?
 
J

Jon Skeet [C# MVP]

3. The code for creating the object is like this:
Type type = Assembly.LoadFrom(assemblyName,
securityAttributes).GetType(typeName, true, ignoreCase);
object obj = type.GetConstructor(bindingAttr, binder,
callConvention, types, modifiers).
Invoke(bindingAttr, binder, parameters, culture);
return obj;

Aha - so it's loading an assembly explicitly. That's likely to be
relevant.
When i view the type and obj in the debugger, i can see that the type
is correct and the object is of correct type. Atleast it seems to me
that they are correct.

I suspect this is not true. At least, not when you study it in detail -
see below.
Infact in the step 3 mentioned above, i can debug into the ctor of A.
So i can be sure that it's class A's ctor that is being called and not
some other class with the same name.

So after object a = myReflectedFunction("MyNamespace.A");
this line
a.GetType().Equals(typeof(MyNamespace.A)
returns false!!
Any idea as to how i can see why the above line returns false?

Yes - I suspect they come from different Assembly objects. Now, I have
to confess that I've never really understood *exactly* under what
circumstances Assembly.LoadFrom creates a new instance of Assembly and
under what circumstances it uses one which is already loaded. However,
I *have* seen this kind of situation before. (In particular, I've seen
a situation where a unit test gives a different result depending on
which test runner is running it!)

I'm sorry not to have enough time to investigate further for you, but
hopefully that will at least give you an avenue of enquiry to pursue.
 
G

GeezerButler

Do you by any chance have B defined in multiple assemblies? If so, that
would certainly explain things somewhat.

--
Jon Skeet - <[email protected]>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too- Hide quoted text -

- Show quoted text -

Jon,
You always have some sort of an answer to my questions (though i dont
always fully understand them)
Thanks, though i did not expect the type A to be in 2 different
assemblies, but that was indeed the problem.
I found the differences in the Types by using The Object Comparer that
i wrote a few days back, woth which you helped me too!
But i am still confused about the whole thing.

Let me explain a little bit.
I have 3 projects in my soln:
1. MyNamespace.dll (Dll that i am writing)
2. ObjectFactory.dll (Third party dll for creating objects
dynamically)
3. ToTestIt.exe (Console application which i add to all my solutions
for testing the dll that i write)

Now, the offending code

object obj = ObjectFactory.MyReflectionFunction("classA");
A objA = (A) obj;
if (a.GetType().Equals(typeof(MyNamespace.A))
{
throw Exception();
}

is in a function in MyClass in MyNamespace project.
I call this function from the ToTestIt exe.

Now the "typeof(MyNamespace.A)" code above has 'module' as "path/
ToTestIt/bin/debug/MyNamespace.dll" and not
"path/MyNamespace/bin/debug/MyNamespace.dll".
I can't seem to understand why this is the case? Can you help me with
this.
Hope you could understand my question.
 
J

Jon Skeet [C# MVP]

Let me explain a little bit.
I have 3 projects in my soln:
1. MyNamespace.dll (Dll that i am writing)
2. ObjectFactory.dll (Third party dll for creating objects
dynamically)
3. ToTestIt.exe (Console application which i add to all my solutions
for testing the dll that i write)

Now the "typeof(MyNamespace.A)" code above has 'module' as "path/
ToTestIt/bin/debug/MyNamespace.dll" and not
"path/MyNamespace/bin/debug/MyNamespace.dll".
I can't seem to understand why this is the case? Can you help me with
this.
Hope you could understand my question.

Aha - good, this is a lot simpler than I'd previously feared then :)

When you build ToTestIt.exe, it will copy both of the other DLLs to the
same output folder (at least if the Copy Local property of each
reference is set to true).

When you run ToTestIt.exe, those "local" copies of the assemblies are
being used. When you explicitly load a different filename, it's
treating it as a different assembly - I expect!
 
A

Adam Benson

When you run ToTestIt.exe, those "local" copies of the assemblies are
being used. When you explicitly load a different filename, it's
treating it as a different assembly - I expect!

Definitely. We've had migraines over the same sort of behaviour.

The "same" object in 2 copies of the "same" dll are not the same.
We had a bad deployment that put one copy of the dll in a libs directory and
another copy in the exe directory.
Casting failed for objects to their own type, because the code attempting
the cast was being given an evil twin rather than the real thing.

Delete one of the dlls and you're OK.

- Adam.
========
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top