.NET Framework Developer Center >
.NET Development Forums
>
.NET Base Class Library
>
Casting question
Casting question
- Hi , I have a question on polymorphism: 2 classes
public class1
{
}
public class2 : class1
{
}
class2 is a carbon copy of class1, except that class 2 is equpped with Linq attributes ([Table], [Column] etc.
When casting class2 type to class1 type, the type remains that of class2. Is this correct ???
Answers
- Expose B on your service method. When you generate the WSDL on the client side, it's going to generate only what it knows about B. You'll notice once the class comes over the wire, it'll no longer be A, it'll be B, but on the server side, it'll remain as A. That's normal and perfectly acceptable.Think of it this way.HumanBeing stevie = new HumanBeing();Mammal someMammal = (Mammal)stevie;someMammal doesn't cease to be a HumanBeing. It was, and always is, a human being. Only, from someMammal, I can only access the mammal traits and none of the human being specific traits of stevie. Thus I could say:someMammal.BreatheAir();But I couldn't say:someMammal.SpeakEnglish();Though I was able to say:stevie.SpeakEnglish();Doesn't mean someMammal can't speak english. It just means that you don't have access to tell someMammal to speak English while referring to it simply as a mammal.If all you need on the client side it the ability to refer to something as a "Mammal", that's fine. Expose the "HumanBeing" from the service as a Mammal and not as a HumanBeing. Everything should work just fine.
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser- Proposed As Answer byMarcel Roma Thursday, November 05, 2009 11:48 AM
- Marked As Answer byeryangMSFT, ModeratorMonday, November 09, 2009 8:03 AM
All Replies
- Depends on what you mean by "the type". There's the instantiated type, and the declared type. The declared type is the type of the variable, while the instantiated type is the actual type of the value represented by the variable, if that makes sense...
class1 value = new class2();
In the above scenario, the declared type is class1, but the instantiated type is class2. You can still cast the "value" back to class2 without issues, which would give you a variable where the instantiated and declared type is class2.
class2 value2 = (class2)value; // declared and instantiated the same
But to be sure, none of your information is lost when you cast to a base class.
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser - Hi ,, thx, I understand in full, but it does not answer my question. Maybe some more info:
I have a class which is part of a client-server app. The class needs to be known on both sides (client and server), because it gets serialised over the wire. The objects, instantiated from the class are stored in an SQL db, meaning that the class declaration also has Table and Column attributes attached to it. The client app is silverlight which does not like Table and Column attributes (there are not the necessary Linq libs in Silverlight).
To solve this, my idea was to have a server side definition of the class (with the necessary Table/Column attributes, lets call it class A), and a client side definition of the same class, but without the attributes (lets call that class B). I would make B known the the client, and A and B known to the server. A derives from B.
Now to extract the info from SQL I need to use class A, but I cannot send A over the wire, because the client only knows about class B. I thought that as A derives from B, I could simply cast A to B, and send it over the wire.
Only when I cast A to B, the type remains A. (????) - Expose B on your service method. When you generate the WSDL on the client side, it's going to generate only what it knows about B. You'll notice once the class comes over the wire, it'll no longer be A, it'll be B, but on the server side, it'll remain as A. That's normal and perfectly acceptable.Think of it this way.HumanBeing stevie = new HumanBeing();Mammal someMammal = (Mammal)stevie;someMammal doesn't cease to be a HumanBeing. It was, and always is, a human being. Only, from someMammal, I can only access the mammal traits and none of the human being specific traits of stevie. Thus I could say:someMammal.BreatheAir();But I couldn't say:someMammal.SpeakEnglish();Though I was able to say:stevie.SpeakEnglish();Doesn't mean someMammal can't speak english. It just means that you don't have access to tell someMammal to speak English while referring to it simply as a mammal.If all you need on the client side it the ability to refer to something as a "Mammal", that's fine. Expose the "HumanBeing" from the service as a Mammal and not as a HumanBeing. Everything should work just fine.
Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki • LinkedIn • ForumsBrowser- Proposed As Answer byMarcel Roma Thursday, November 05, 2009 11:48 AM
- Marked As Answer byeryangMSFT, ModeratorMonday, November 09, 2009 8:03 AM
- Hi .. This is what I have tried, and the class will not go over the wire:
Class B is exposed to the client
Class A and B are exposed on server side. A derives from B and is equal in fields/properties etc etc, Except that A (not exposed to the client) is equipped with Linq attributes.
What will go over the wire: B objectb = new B();
What will not go over the wire: A objecta =new A(); B objectb1 = (B)objecta; - Hi .. have done a trace and isolated the exception:
There was an error while trying to serialize parameter http://Spinwizard:CommandResult. The InnerException message was 'Type 'ControlBloks.ArtistInformationBlok' with data contract name 'ArtistInformationBlok:http://Spinwizard' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
In this message, "ArtistInformationBlok" is class A. A is not known to the client, and the client is expecting B which is why I am casting from A to B before sending it over the wire. The message speaks of serialisation problems (not deserialisation), so it seems the service is having problems putting it on the wire. - Hi .. as far as I can see the cause is simple: the contract serializer is not seeing the class as B, although I have explicitly cast it to be of that type. Anybody any idea's ???


