RadhaKrishnaKiJaya
asked on
Specified cast is not valid
Hi Experts,
I am trying to create a property class CCObject2 with 5 sets and gets, which is identical to another property class CCObject. My code works when using CCObject. But when I am using CCObject2, I get the error below. Any idea what could be going on? Thank you very much in advance!
Error Message
--------------------------
Specified cast is not valid
CCObject2 creditObject = (CCObject2)ObjectDeseriali ze(decrypt edInfo);
Original Working Code
-------------------------- ---------- -------
CreditCardEncryption ccService = new CreditCardEncryption();
decryptedInfo = ccService.DecryptData(encr yptedData) ;
CCObject creditObject = (CCObject)ObjectDeserializ e(decrypte dInfo);
Non Working Code
-------------------------- ---------- -
CreditCardEncryption ccService = new CreditCardEncryption();
decryptedInfo = ccService.DecryptData(encr yptedData) ;
CCObject2 creditObject = (CCObject2)ObjectDeseriali ze(decrypt edInfo);
I am trying to create a property class CCObject2 with 5 sets and gets, which is identical to another property class CCObject. My code works when using CCObject. But when I am using CCObject2, I get the error below. Any idea what could be going on? Thank you very much in advance!
Error Message
--------------------------
Specified cast is not valid
CCObject2 creditObject = (CCObject2)ObjectDeseriali
Original Working Code
--------------------------
CreditCardEncryption ccService = new CreditCardEncryption();
decryptedInfo = ccService.DecryptData(encr
CCObject creditObject = (CCObject)ObjectDeserializ
Non Working Code
--------------------------
CreditCardEncryption ccService = new CreditCardEncryption();
decryptedInfo = ccService.DecryptData(encr
CCObject2 creditObject = (CCObject2)ObjectDeseriali
You could use a little bit of deception.
Deserialise as the original object. Then the object you really require has a constructor which takes the first object and just copies the fields from the first object into itself (this second object).
Deserialise as the original object. Then the object you really require has a constructor which takes the first object and just copies the fields from the first object into itself (this second object).
Try deserializing first in the original object, and then cast it to the new one.
CCObject2 creditObject = (CCObject2)((CCObject)Obje ctDeserial ize(decryp tedInfo));
If this does not work, then the formats are not compatible. In such a case, Andy's solution is the only one available.
You often have to do that anyway if you make changes in the original class. If some properties change between 2 versions of a class, then deserialization usually fails and you need to have some kind of conversion routine to read the old format into the new class.
CCObject2 creditObject = (CCObject2)((CCObject)Obje
If this does not work, then the formats are not compatible. In such a case, Andy's solution is the only one available.
You often have to do that anyway if you make changes in the original class. If some properties change between 2 versions of a class, then deserialization usually fails and you need to have some kind of conversion routine to read the old format into the new class.
What kind of serialization are you performing? With XML serialization (and a bit of attribute wizardry) you should be able to deserialize into the other type. If this is binary serialization, then not so much.
ASKER
Thank you all for your help. Here is the issue. Initially I had 5 properties in original one i.e. CCObject. Later on I added 3 more to it. When working on the newly added data, I have no problem. But, problem with existing data, they still have 5 properties. When trying decrypt 5 items to the original one (which got 8 properties already), getting the error. I am still unable to understand why can't I use the 2nd object CCObject2. Thank you all again!
>>I am still unable to understand why can't I use the 2nd object CCObject2
To expand on the explanation by sedgwick.
string s = (string)42; //wrong, 42 is a number NOT a string
int i = (int)"42"; //wrong, "42" is a string not a number
You cannot tell the compiler (in C#) that a piece of chalk is a piece of cheese. Unless the two objects are in a parent-child or similar relationship such casting is disallowed. Some languages allow you to do that but it is often short cut to disaster.
As I said earlier you can easily get around it:
Obj1 o = (Obj1)deserialise();
Obj2 o2 = new Obj2(o); //Obj2 will copy the data from the first type of object - you code that
To expand on the explanation by sedgwick.
string s = (string)42; //wrong, 42 is a number NOT a string
int i = (int)"42"; //wrong, "42" is a string not a number
You cannot tell the compiler (in C#) that a piece of chalk is a piece of cheese. Unless the two objects are in a parent-child or similar relationship such casting is disallowed. Some languages allow you to do that but it is often short cut to disaster.
As I said earlier you can easily get around it:
Obj1 o = (Obj1)deserialise();
Obj2 o2 = new Obj2(o); //Obj2 will copy the data from the first type of object - you code that
ASKER
AndyAinscow, First of all Thank you. I have no words.
I understand what you are talking about. In this case I will get the exact copy of Obj1. But my problem is totally different. I am trying to cast my data w/o knowing howmany fields they have in each row in DB. It could be 8 or 5.
Let me explan you what kind of data I have in my db. In some rows, I have only 5 fields and in some rows I have 8 fields. They are all combined in 1 column in the db and saved. Here the goal is to deserialise them, no matter what (5 or 8 fields).
If I try to deserialise with Obj1 with 8 properties, when I have 8 columns in the db, I don't have any problem. But if I have only 5 columns, immediately I get error "Object reference not set to an instance of an object". Also, when I have 5 fields in the DB, I can't cast with Obj1 as it has got 8 properties.
For this reason, I If I tried to create 2 objects Obj1 (8 properties) and Obj2 (5 properties)
If I get error with the Obj1, immediately I tried to deserialise with Obj2. This idea failed miserably.
I hope I explained to you in a better way this time. Please let me know if there is any confusion.
Thank you again for your time and help! I really appricate it.
I understand what you are talking about. In this case I will get the exact copy of Obj1. But my problem is totally different. I am trying to cast my data w/o knowing howmany fields they have in each row in DB. It could be 8 or 5.
Let me explan you what kind of data I have in my db. In some rows, I have only 5 fields and in some rows I have 8 fields. They are all combined in 1 column in the db and saved. Here the goal is to deserialise them, no matter what (5 or 8 fields).
If I try to deserialise with Obj1 with 8 properties, when I have 8 columns in the db, I don't have any problem. But if I have only 5 columns, immediately I get error "Object reference not set to an instance of an object". Also, when I have 5 fields in the DB, I can't cast with Obj1 as it has got 8 properties.
For this reason, I If I tried to create 2 objects Obj1 (8 properties) and Obj2 (5 properties)
If I get error with the Obj1, immediately I tried to deserialise with Obj2. This idea failed miserably.
I hope I explained to you in a better way this time. Please let me know if there is any confusion.
Thank you again for your time and help! I really appricate it.
Before you deserialise you could inspect the data to determine which object will be used. For example if you use a comma as a separator then if there is more than 5 commas in the column then it is an '8' object else it is a '5' object.
ASKER
I am not using coma to seperate them. But use the same Obj1 as below to save.
Obj1.CCName = txtCCName.Text
Obj1.CCNum = txtCCNum.Text
.
.
byte[] cCObj=ObjectSerialize(Obj1 );
Any other idea?
Obj1.CCName = txtCCName.Text
Obj1.CCNum = txtCCNum.Text
.
.
byte[] cCObj=ObjectSerialize(Obj1
Any other idea?
ASKER
AndyAinscow,
I am just tyring to use Obj1 when there are 8 fields, Obj2 when there are 5 fields.
Now, in Obj2 I changed all the property names. Still it is failing as before.
How can I restore the data? There must be some way.
I am just tyring to use Obj1 when there are 8 fields, Obj2 when there are 5 fields.
Now, in Obj2 I changed all the property names. Still it is failing as before.
How can I restore the data? There must be some way.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I am still struggling find a solution for this one. In the meantime I was diverted to another project. Sorry! I will get back to this soon.
ASKER
I've requested that this question be deleted for the following reason:
Remained open for a long time.
Remained open for a long time.
>>Remained open for a long time.
That isn't a reason for deleting. Please review the comments and explain why nothing was suitable OR choose one or more comments for the answer.
That isn't a reason for deleting. Please review the comments and explain why nothing was suitable OR choose one or more comments for the answer.
If I understand correctly comment #39282029 is relevant (essential information to complete the task has not been stored - so impossible to accomplish).
if they are 2 separate objects, the casting will fail.
one exception is, in case they inherit one another the cast may work, so if CCObject2 is base class of CCObject or vise versa.
so in this case:
Open in new window
the following should work:Open in new window