Before I start answering you, it’s important to explain what this code you put in the question is for. I set up a Fiddle to explain how it converts an object to XML.
We declare a class:
public class TesteClasse
{
public TipoDoAmbiente TipoDoAmbiente { get; set; }
}
We instantiate the class with a value of TipoDoAmbiente
:
var classe = new TesteClasse { TipoDoAmbiente = TipoDoAmbiente.Item2 };
We also instantiated a XML serializer and a special object, XmlWriter
, which receives the conversion of an object into XML by the serializer. To write the conversion result, this XmlWriter
needs an object of streaming specialized (written in some type of memory, for example memory or disk). For example, I used StringWriter
:
var xmlSerializer = new XmlSerializer(typeof(TesteClasse));
var stringWriter = new StringWriter();
var xmlWriter = XmlWriter.Create(stringWriter);
Recapping:
- Convert a C# object to XML;
- Write the object to another object that formats XML;
- Convert XML to a
string
XML.
The result of XML is:
<?xml version="1.0" encoding="utf-16"?>
<TesteClasse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<TipoDoAmbiente>2</TipoDoAmbiente>
</TesteClasse>
Notice that I defined TipoAmbiente
as Tipo2
, but the XML serializer wrote only as 2
, according to its definition of attribute.
I’ll do the reverse now. From a string
XML and convert it to the object, but this time using not a XmlWriter
, but a XmlReader
and, similarly, a StringReader
(Fiddle here)
var xml = "<?xml version=\"1.0\" encoding=\"utf-16\"?><TesteClasse xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><TipoDoAmbiente>2</TipoDoAmbiente></TesteClasse>";
var xmlSerializer = new XmlSerializer(typeof(TesteClasse));
TesteClasse testeClasse = (TesteClasse)xmlSerializer.Deserialize(XmlReader.Create(new StringReader(xml)));
Console.WriteLine(testeClasse.TipoDoAmbiente);
The example will write in console Item2
.
Now, to your questions.
The method propriedade.GetValue(objeto, null);
returns the value of Enum, in the case of this test that I made the value is item1
. When I make a debug and stop at the itemEnum
nothing more than the value itself appears.
I take this value and move on to the next methods, my doubt is how the rest of the code "discovers" the type and member information if I’m just passing the value item1
?
If you also want to pass the member’s type and information, it’s not just getting the value of it that will happen. You also need to retrieve the object PropertyInfo
related to the property you want to recover the value. This you have already done here:
foreach (PropertyInfo propriedade in tipo.GetRuntimeProperties()) { ... }
But only passing the value item1
for the code var infoEnum = valorEnum.GetType().GetMember(propriedade.GetValue(objeto, null).ToString()).FirstOrDefault();
it returns the class and property to which it belongs.
Well, this is very wrong. I think what you want is to retrieve an object for the value of TipoDeAmbiente
from what I understand.
In this case, System.Linq
better resolve the situation for you:
// Estou supondo que você desserializou um XML em uma lista, tipo List<TesteClasse>.
var propertiesTipoDeAmbiente = typeof(TesteClasse).GetProperties().Where(p => p.PropertyType == TipoDeAmbiente);
foreach (var propriedade in propertiesTipoDeAmbiente)
{
foreach (var elemento in lista)
{
if (((TipoDeAmbiente)propriedade.GetValue(elemento, null)) == TipoDeAmbiente.Item1)
yield return elemento; // Isto aqui acumula tudo em um IEnumerable<TesteClasse>.
}
}
Last thing
This is pretty slow. Use this Nuget package to read this with a decent performance.
Just want to know how it works internally? Or do you have some difficulty with what you’re doing? See if this helps: http://answall.com/q/13089/101
– Maniero
It would be internally, but I’m also learning, so I have difficulty. But I’d really like to know how the hell that works, because I only passed the value of Enum and it still works. Even though I create two enums with equal values, yet he "discovers" who he is.
– Robss70
I don’t know how to begin to answer, the question is very open. I can answer one thing and be what you want. The answer I showed help in any way? Is there anything else you need to know? Try to make the question a little more specific.
como o resto do código "descobre" o tipo e as informações do membro se só estou passando o o valor item1?
That’s not very clear. What is this example of reflection code doing there? Try to make these things come together and make sense.– Maniero
@bigown, edited the question, see if it got less confused, and if it is possible you help me, I will be very grateful. I read the answer you showed.
– Robss70
I’ll try to answer something, just finish something here.
– Maniero
I didn’t understand it either... even with this edition.
– Miguel Angelo
Just like Overview: the . Net has managed memory, this means that every thing in memory is associated with the metadata of the type to which it belongs. It is the memory manager that does this. So when it is called
xpto.GetType()
the associated metadata is returned so you can consult.– Miguel Angelo
I will try, but this code is too loose, it will be almost a kick. As the question is not very clear will not be able to complain. Ideally it would be better if you had made a [mcve] to show what you are having trouble understanding. Show what you thought, explain better what you didn’t understand. The edition helped a little, but gave more margin. Something was just a repetition of what I had before.
– Maniero