Restore common variables between inherited types











up vote
0
down vote

favorite












I have two classes: GameObject and SampleObject : GameObject and a list of type GameObject. I've serialized instances of these classes into a XML document. My problem occurs once I deserialize (load) this document.



In XML file instances are serialized as:



<Root>
<GameObject>
<Type>Namespace.MyType</Type>
</GameObject>
</Root>


Where Type represents desired type. And each instance is serialized under GameObject tag.



After parsing this document I obtain a list of GameObject. Now I need to restore correct type:



foreach (GameObject g in myList)
{
GameObject tempObject = (GameObject)Activator.CreateInstance(Type.GetType(g.TypeString));
}


Problem is that tempObject is blank (which is correct). I'd like to (with some shorthand) restore common (shared) variables between g and tempObject. Ex:



tempObject.Property1 = g.Property1
tempObject.Property2 = g.Property2









share|improve this question






















  • Wouldn't you need to deserialize SampleObject-specific properties as well?
    – C.Evenhuis
    Nov 18 at 21:58












  • I would. @C.Evenhuis
    – Matěj Štágl
    Nov 18 at 22:18










  • In that case I wouldn't deserialize as GameObject first at all - what type of serializer do you use? XmlSerializer for instance has some built-in support for this.
    – C.Evenhuis
    Nov 19 at 8:03












  • I'm using XmlSerializer
    – Matěj Štágl
    Nov 19 at 11:42















up vote
0
down vote

favorite












I have two classes: GameObject and SampleObject : GameObject and a list of type GameObject. I've serialized instances of these classes into a XML document. My problem occurs once I deserialize (load) this document.



In XML file instances are serialized as:



<Root>
<GameObject>
<Type>Namespace.MyType</Type>
</GameObject>
</Root>


Where Type represents desired type. And each instance is serialized under GameObject tag.



After parsing this document I obtain a list of GameObject. Now I need to restore correct type:



foreach (GameObject g in myList)
{
GameObject tempObject = (GameObject)Activator.CreateInstance(Type.GetType(g.TypeString));
}


Problem is that tempObject is blank (which is correct). I'd like to (with some shorthand) restore common (shared) variables between g and tempObject. Ex:



tempObject.Property1 = g.Property1
tempObject.Property2 = g.Property2









share|improve this question






















  • Wouldn't you need to deserialize SampleObject-specific properties as well?
    – C.Evenhuis
    Nov 18 at 21:58












  • I would. @C.Evenhuis
    – Matěj Štágl
    Nov 18 at 22:18










  • In that case I wouldn't deserialize as GameObject first at all - what type of serializer do you use? XmlSerializer for instance has some built-in support for this.
    – C.Evenhuis
    Nov 19 at 8:03












  • I'm using XmlSerializer
    – Matěj Štágl
    Nov 19 at 11:42













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have two classes: GameObject and SampleObject : GameObject and a list of type GameObject. I've serialized instances of these classes into a XML document. My problem occurs once I deserialize (load) this document.



In XML file instances are serialized as:



<Root>
<GameObject>
<Type>Namespace.MyType</Type>
</GameObject>
</Root>


Where Type represents desired type. And each instance is serialized under GameObject tag.



After parsing this document I obtain a list of GameObject. Now I need to restore correct type:



foreach (GameObject g in myList)
{
GameObject tempObject = (GameObject)Activator.CreateInstance(Type.GetType(g.TypeString));
}


Problem is that tempObject is blank (which is correct). I'd like to (with some shorthand) restore common (shared) variables between g and tempObject. Ex:



tempObject.Property1 = g.Property1
tempObject.Property2 = g.Property2









share|improve this question













I have two classes: GameObject and SampleObject : GameObject and a list of type GameObject. I've serialized instances of these classes into a XML document. My problem occurs once I deserialize (load) this document.



In XML file instances are serialized as:



<Root>
<GameObject>
<Type>Namespace.MyType</Type>
</GameObject>
</Root>


Where Type represents desired type. And each instance is serialized under GameObject tag.



After parsing this document I obtain a list of GameObject. Now I need to restore correct type:



foreach (GameObject g in myList)
{
GameObject tempObject = (GameObject)Activator.CreateInstance(Type.GetType(g.TypeString));
}


Problem is that tempObject is blank (which is correct). I'd like to (with some shorthand) restore common (shared) variables between g and tempObject. Ex:



tempObject.Property1 = g.Property1
tempObject.Property2 = g.Property2






c# reflection






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 18 at 20:25









Matěj Štágl

473222




473222












  • Wouldn't you need to deserialize SampleObject-specific properties as well?
    – C.Evenhuis
    Nov 18 at 21:58












  • I would. @C.Evenhuis
    – Matěj Štágl
    Nov 18 at 22:18










  • In that case I wouldn't deserialize as GameObject first at all - what type of serializer do you use? XmlSerializer for instance has some built-in support for this.
    – C.Evenhuis
    Nov 19 at 8:03












  • I'm using XmlSerializer
    – Matěj Štágl
    Nov 19 at 11:42


















  • Wouldn't you need to deserialize SampleObject-specific properties as well?
    – C.Evenhuis
    Nov 18 at 21:58












  • I would. @C.Evenhuis
    – Matěj Štágl
    Nov 18 at 22:18










  • In that case I wouldn't deserialize as GameObject first at all - what type of serializer do you use? XmlSerializer for instance has some built-in support for this.
    – C.Evenhuis
    Nov 19 at 8:03












  • I'm using XmlSerializer
    – Matěj Štágl
    Nov 19 at 11:42
















Wouldn't you need to deserialize SampleObject-specific properties as well?
– C.Evenhuis
Nov 18 at 21:58






Wouldn't you need to deserialize SampleObject-specific properties as well?
– C.Evenhuis
Nov 18 at 21:58














I would. @C.Evenhuis
– Matěj Štágl
Nov 18 at 22:18




I would. @C.Evenhuis
– Matěj Štágl
Nov 18 at 22:18












In that case I wouldn't deserialize as GameObject first at all - what type of serializer do you use? XmlSerializer for instance has some built-in support for this.
– C.Evenhuis
Nov 19 at 8:03






In that case I wouldn't deserialize as GameObject first at all - what type of serializer do you use? XmlSerializer for instance has some built-in support for this.
– C.Evenhuis
Nov 19 at 8:03














I'm using XmlSerializer
– Matěj Štágl
Nov 19 at 11:42




I'm using XmlSerializer
– Matěj Štágl
Nov 19 at 11:42












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










XmlSerializer supports polymorphism, but you'll have to indicate up front which types to exprect. You can do this using an attribute on the base type:



[XmlInclude(typeof(SampleObject))]
public class GameObject
{
}


You can also pass these types to the constructor of XmlSerializer, for instance if you don't own the GameObject class. Full example:



Root root = new Root();
root.Objects.Add(new GameObject { Property1 = 2 });
root.Objects.Add(new SampleObject { Property1 = 5, Property2 = 12 });

XmlSerializer ser = new XmlSerializer(typeof(Root), new Type { typeof(SampleObject) });
using (MemoryStream stream = new MemoryStream())
{
ser.Serialize(stream, root);
stream.Position = 0;
Root deserialized = (Root)ser.Deserialize(stream);
}


It outputs the following xml:



<?xml version="1.0"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GameObject>
<Property1>2</Property1>
</GameObject>
<GameObject xsi:type="SampleObject">
<Property1>5</Property1>
<Property2>12</Property2>
</GameObject>
</Root>


I used the below classes for this example:



[XmlRoot]
public class Root
{
public Root()
{
Objects = new List<GameObject>();
}

[XmlElement("GameObject")]
public List<GameObject> Objects { get; set; }
}

public class GameObject
{
public int Property1 { get; set; }
}

public class SampleObject : GameObject
{
public int Property2 { get; set; }
}





share|improve this answer





















  • This actually connected gaps in my knowledge. I already had output in format of <GameObject xsi:type="SampleObject"> but had no idea how to use this xsi:type. Just for clarification, could you extend your answer with how'd the situation change if there was one more type, ex. SampleObject2?
    – Matěj Štágl
    Nov 19 at 12:07












  • And one more question. Imagine that there are plenty of these types inheriting from GameObject. Is there any way to automate extension of [XmlInclude(typeof(SampleObject))] or do I have to add every type by hand?
    – Matěj Štágl
    Nov 19 at 12:12








  • 1




    You could use reflection on startup to collect all types inheriting from GameObject and store them in a Type - which you can then supply to the XmlSerializer constructor.
    – C.Evenhuis
    Nov 19 at 12:48












  • Great, thanks Evenhuis
    – Matěj Štágl
    Nov 19 at 12:50











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53365092%2frestore-common-variables-between-inherited-types%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










XmlSerializer supports polymorphism, but you'll have to indicate up front which types to exprect. You can do this using an attribute on the base type:



[XmlInclude(typeof(SampleObject))]
public class GameObject
{
}


You can also pass these types to the constructor of XmlSerializer, for instance if you don't own the GameObject class. Full example:



Root root = new Root();
root.Objects.Add(new GameObject { Property1 = 2 });
root.Objects.Add(new SampleObject { Property1 = 5, Property2 = 12 });

XmlSerializer ser = new XmlSerializer(typeof(Root), new Type { typeof(SampleObject) });
using (MemoryStream stream = new MemoryStream())
{
ser.Serialize(stream, root);
stream.Position = 0;
Root deserialized = (Root)ser.Deserialize(stream);
}


It outputs the following xml:



<?xml version="1.0"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GameObject>
<Property1>2</Property1>
</GameObject>
<GameObject xsi:type="SampleObject">
<Property1>5</Property1>
<Property2>12</Property2>
</GameObject>
</Root>


I used the below classes for this example:



[XmlRoot]
public class Root
{
public Root()
{
Objects = new List<GameObject>();
}

[XmlElement("GameObject")]
public List<GameObject> Objects { get; set; }
}

public class GameObject
{
public int Property1 { get; set; }
}

public class SampleObject : GameObject
{
public int Property2 { get; set; }
}





share|improve this answer





















  • This actually connected gaps in my knowledge. I already had output in format of <GameObject xsi:type="SampleObject"> but had no idea how to use this xsi:type. Just for clarification, could you extend your answer with how'd the situation change if there was one more type, ex. SampleObject2?
    – Matěj Štágl
    Nov 19 at 12:07












  • And one more question. Imagine that there are plenty of these types inheriting from GameObject. Is there any way to automate extension of [XmlInclude(typeof(SampleObject))] or do I have to add every type by hand?
    – Matěj Štágl
    Nov 19 at 12:12








  • 1




    You could use reflection on startup to collect all types inheriting from GameObject and store them in a Type - which you can then supply to the XmlSerializer constructor.
    – C.Evenhuis
    Nov 19 at 12:48












  • Great, thanks Evenhuis
    – Matěj Štágl
    Nov 19 at 12:50















up vote
1
down vote



accepted










XmlSerializer supports polymorphism, but you'll have to indicate up front which types to exprect. You can do this using an attribute on the base type:



[XmlInclude(typeof(SampleObject))]
public class GameObject
{
}


You can also pass these types to the constructor of XmlSerializer, for instance if you don't own the GameObject class. Full example:



Root root = new Root();
root.Objects.Add(new GameObject { Property1 = 2 });
root.Objects.Add(new SampleObject { Property1 = 5, Property2 = 12 });

XmlSerializer ser = new XmlSerializer(typeof(Root), new Type { typeof(SampleObject) });
using (MemoryStream stream = new MemoryStream())
{
ser.Serialize(stream, root);
stream.Position = 0;
Root deserialized = (Root)ser.Deserialize(stream);
}


It outputs the following xml:



<?xml version="1.0"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GameObject>
<Property1>2</Property1>
</GameObject>
<GameObject xsi:type="SampleObject">
<Property1>5</Property1>
<Property2>12</Property2>
</GameObject>
</Root>


I used the below classes for this example:



[XmlRoot]
public class Root
{
public Root()
{
Objects = new List<GameObject>();
}

[XmlElement("GameObject")]
public List<GameObject> Objects { get; set; }
}

public class GameObject
{
public int Property1 { get; set; }
}

public class SampleObject : GameObject
{
public int Property2 { get; set; }
}





share|improve this answer





















  • This actually connected gaps in my knowledge. I already had output in format of <GameObject xsi:type="SampleObject"> but had no idea how to use this xsi:type. Just for clarification, could you extend your answer with how'd the situation change if there was one more type, ex. SampleObject2?
    – Matěj Štágl
    Nov 19 at 12:07












  • And one more question. Imagine that there are plenty of these types inheriting from GameObject. Is there any way to automate extension of [XmlInclude(typeof(SampleObject))] or do I have to add every type by hand?
    – Matěj Štágl
    Nov 19 at 12:12








  • 1




    You could use reflection on startup to collect all types inheriting from GameObject and store them in a Type - which you can then supply to the XmlSerializer constructor.
    – C.Evenhuis
    Nov 19 at 12:48












  • Great, thanks Evenhuis
    – Matěj Štágl
    Nov 19 at 12:50













up vote
1
down vote



accepted







up vote
1
down vote



accepted






XmlSerializer supports polymorphism, but you'll have to indicate up front which types to exprect. You can do this using an attribute on the base type:



[XmlInclude(typeof(SampleObject))]
public class GameObject
{
}


You can also pass these types to the constructor of XmlSerializer, for instance if you don't own the GameObject class. Full example:



Root root = new Root();
root.Objects.Add(new GameObject { Property1 = 2 });
root.Objects.Add(new SampleObject { Property1 = 5, Property2 = 12 });

XmlSerializer ser = new XmlSerializer(typeof(Root), new Type { typeof(SampleObject) });
using (MemoryStream stream = new MemoryStream())
{
ser.Serialize(stream, root);
stream.Position = 0;
Root deserialized = (Root)ser.Deserialize(stream);
}


It outputs the following xml:



<?xml version="1.0"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GameObject>
<Property1>2</Property1>
</GameObject>
<GameObject xsi:type="SampleObject">
<Property1>5</Property1>
<Property2>12</Property2>
</GameObject>
</Root>


I used the below classes for this example:



[XmlRoot]
public class Root
{
public Root()
{
Objects = new List<GameObject>();
}

[XmlElement("GameObject")]
public List<GameObject> Objects { get; set; }
}

public class GameObject
{
public int Property1 { get; set; }
}

public class SampleObject : GameObject
{
public int Property2 { get; set; }
}





share|improve this answer












XmlSerializer supports polymorphism, but you'll have to indicate up front which types to exprect. You can do this using an attribute on the base type:



[XmlInclude(typeof(SampleObject))]
public class GameObject
{
}


You can also pass these types to the constructor of XmlSerializer, for instance if you don't own the GameObject class. Full example:



Root root = new Root();
root.Objects.Add(new GameObject { Property1 = 2 });
root.Objects.Add(new SampleObject { Property1 = 5, Property2 = 12 });

XmlSerializer ser = new XmlSerializer(typeof(Root), new Type { typeof(SampleObject) });
using (MemoryStream stream = new MemoryStream())
{
ser.Serialize(stream, root);
stream.Position = 0;
Root deserialized = (Root)ser.Deserialize(stream);
}


It outputs the following xml:



<?xml version="1.0"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GameObject>
<Property1>2</Property1>
</GameObject>
<GameObject xsi:type="SampleObject">
<Property1>5</Property1>
<Property2>12</Property2>
</GameObject>
</Root>


I used the below classes for this example:



[XmlRoot]
public class Root
{
public Root()
{
Objects = new List<GameObject>();
}

[XmlElement("GameObject")]
public List<GameObject> Objects { get; set; }
}

public class GameObject
{
public int Property1 { get; set; }
}

public class SampleObject : GameObject
{
public int Property2 { get; set; }
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 19 at 12:01









C.Evenhuis

21.7k24159




21.7k24159












  • This actually connected gaps in my knowledge. I already had output in format of <GameObject xsi:type="SampleObject"> but had no idea how to use this xsi:type. Just for clarification, could you extend your answer with how'd the situation change if there was one more type, ex. SampleObject2?
    – Matěj Štágl
    Nov 19 at 12:07












  • And one more question. Imagine that there are plenty of these types inheriting from GameObject. Is there any way to automate extension of [XmlInclude(typeof(SampleObject))] or do I have to add every type by hand?
    – Matěj Štágl
    Nov 19 at 12:12








  • 1




    You could use reflection on startup to collect all types inheriting from GameObject and store them in a Type - which you can then supply to the XmlSerializer constructor.
    – C.Evenhuis
    Nov 19 at 12:48












  • Great, thanks Evenhuis
    – Matěj Štágl
    Nov 19 at 12:50


















  • This actually connected gaps in my knowledge. I already had output in format of <GameObject xsi:type="SampleObject"> but had no idea how to use this xsi:type. Just for clarification, could you extend your answer with how'd the situation change if there was one more type, ex. SampleObject2?
    – Matěj Štágl
    Nov 19 at 12:07












  • And one more question. Imagine that there are plenty of these types inheriting from GameObject. Is there any way to automate extension of [XmlInclude(typeof(SampleObject))] or do I have to add every type by hand?
    – Matěj Štágl
    Nov 19 at 12:12








  • 1




    You could use reflection on startup to collect all types inheriting from GameObject and store them in a Type - which you can then supply to the XmlSerializer constructor.
    – C.Evenhuis
    Nov 19 at 12:48












  • Great, thanks Evenhuis
    – Matěj Štágl
    Nov 19 at 12:50
















This actually connected gaps in my knowledge. I already had output in format of <GameObject xsi:type="SampleObject"> but had no idea how to use this xsi:type. Just for clarification, could you extend your answer with how'd the situation change if there was one more type, ex. SampleObject2?
– Matěj Štágl
Nov 19 at 12:07






This actually connected gaps in my knowledge. I already had output in format of <GameObject xsi:type="SampleObject"> but had no idea how to use this xsi:type. Just for clarification, could you extend your answer with how'd the situation change if there was one more type, ex. SampleObject2?
– Matěj Štágl
Nov 19 at 12:07














And one more question. Imagine that there are plenty of these types inheriting from GameObject. Is there any way to automate extension of [XmlInclude(typeof(SampleObject))] or do I have to add every type by hand?
– Matěj Štágl
Nov 19 at 12:12






And one more question. Imagine that there are plenty of these types inheriting from GameObject. Is there any way to automate extension of [XmlInclude(typeof(SampleObject))] or do I have to add every type by hand?
– Matěj Štágl
Nov 19 at 12:12






1




1




You could use reflection on startup to collect all types inheriting from GameObject and store them in a Type - which you can then supply to the XmlSerializer constructor.
– C.Evenhuis
Nov 19 at 12:48






You could use reflection on startup to collect all types inheriting from GameObject and store them in a Type - which you can then supply to the XmlSerializer constructor.
– C.Evenhuis
Nov 19 at 12:48














Great, thanks Evenhuis
– Matěj Štágl
Nov 19 at 12:50




Great, thanks Evenhuis
– Matěj Štágl
Nov 19 at 12:50


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53365092%2frestore-common-variables-between-inherited-types%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Ottavio Pratesi

Tricia Helfer

15 giugno