It is not using at the same time, it is making a structure and then a class. There is no problem in general, at least not because there are both. But this case seems to be quite wrong.
The organization is right, but the correct thing would be to have two classes*.
Why can’t you use struct
in Endereço
?
There are two "impediments".
First she is very big. She will have 4 words (whereas it will not grow in the future). 32-bit architecture is 16 bytes. 64-bit architecture is 32 bytes. Only pointers to text are stored in the structure.
This is a lot of things, it is at the limit of recommended, but can grow, has no ZIP code, may need more things, such as "add-on" or "indication of location". Structures should only have up to 16 bytes. I’ve done some tests and I saw that it gives good results with bigger sizes, but I know what I’m doing and when you want to go over the official recommendation, it’s very nuanced, if you don’t understand everything, it’s best to stay in the recommendation.
The problem is that structures are types per value and they are passed by copy, can be inefficient if it is too large.
Precisely because they are by value people do not understand the semantics well when they change their data.
When you copy data from a variable by value (struct
) another object is created, so moving on one does not touch the other. And there is a lot of copying that the person does not even realize it occurs. In the case of types by reference (class
) the copy is of the pointer and not of the object itself, so it is always the same object. Moved it, all references to it will see the modification. Marco Giovanni’s answer shows how this occurs.
Structures must be immutable, or change everything and you get a new object or change nothing. This does not seem to be the case Endereco
. The data can be changed independently. In fact there is no mechanism protecting it.
Have you ever paid attention to the C# guys who are structs
? All things small and indivisible.
There are exceptions
If you know very well what you are doing can abuse the structures to gain performance relieve the Garbage Collector. This site you are using now does a lot of this in your software. In the cases that need to avoid copying it uses the ref
. What alias, with new features of C# 7, will tend to be used more and more in systems where performance and memory management matters more.
The new features that are coming in the next versions will help ensure immutability, even if you can do it now.
Again, everything can if you know all the implications of its use.
Note that some classes prefer to be immutable. String
is the most obvious case. There are those who say that everything should be immutable and this is done in other languages. It has its disadvantages there.
To understand better read What’s the difference between Struct and Class?.
Eric Lippert talks in detail and few people have more authority over it than him. The example he sets is great:
struct Mutable {
private int x;
public int Mutate() {
this.x = this.x + 1;
return this.x;
}
}
class Test {
public readonly Mutable m = new Mutable();
static void Main(string[] args) {
Test t = new Test();
System.Console.WriteLine(t.m.Mutate());
System.Console.WriteLine(t.m.Mutate());
System.Console.WriteLine(t.m.Mutate());
}
}
Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.
What does he do? (This is a quiz, answer before seeing the above execution)
Prints 1, 2, 3 - why m
is readonly
, although this applies only to the variable and not its members.
Prints 0, 0, 0 - why m
is readonly
, x cannot be changed and always has default value 0.
It throws an exception when so much change the member’s state, which it believes to be readonly
(is not declared, but thinks it is transferred from variable to member.
Prints 1, 1, 1. Because as the data is copied on each access, it does not use the previous state. When using t.m
, you take a copy of what is on m
. m
is immutable (by readonly
), but your copy is not.
There may be problems with this approach, even if I use a class, but I won’t talk because it’s not the focus of the question. You may also have other problems with the code. But there’s no context, it’s hard to say.
*Note that I haven’t even analyzed whether the address should actually be a separate entity. This could be an error in your case. I have no way to evaluate this.
Thank you so much for the reply. And I will read the links you posted during the text. Thank you!
– Rogério