Why is it forbidden to inherit from significant types, such as struct ? The fact that struct sealed is understandable :) But why was it sealed ?
- @andreycha, after all, the question was about structures, and the leading and only answer at the moment about them, and not about all relevant types. - 4per
- one@ 4per and there is no difference. - andreycha
1 answer
The problem is this. Suppose it were allowed to inherit from structures.
Consider this code:
class C1 { int x; } class C2 : C1 { int y; public override string ToString() { return y.ToString(); } } You can write this: C1 c = new C2(); and call c.ToString(); . Since c is merely a reference to data, there is no problem with the call. This is a standard feature, the basic polymorphic behavior of reference types.
Imagine now a similar situation:
struct S1 { int x; } struct S2 : S1 { int y; public override string ToString() { return y.ToString(); } } S1 s = new S2(); What will be in s ? For efficiency reasons, structures are stored in memory as they are , that is, just a set of fields, and not a link to them. This means that as many bytes as S1 allocated for s , there is simply no room for the y field! What should the call to s.ToString() return in this case?
A similar problem occurs when passing the parameters of a derived type to a function that requires an argument of the base type.
This problem is called slicing , and it is relevant for the design of many programming languages. For example, it is present in C ++. The solution in C # is to abandon the inheritance of structures: to allow idle polymorphism during inheritance is a bad idea. With this solution, slicing in C # is excluded.
Other languages solve the problem differently. For example, in C ++, the real type of the object s is simply S1 , not S2 , and y simply lost. The creators of the C # language consider this behavior non-intuitive, leading to problems and errors, so they took a different path. If you need inheritance, in C # you need to use classes, or go to composition.
The problem could be solved if the structures were stored in the same way as the classes: not a value, but a link to it. At the same time, operations like assignments would not have to copy the link to save the semantics, but the value anyway. But such an approach, although it would allow the inheritance of structures, would greatly impair their effectiveness : each operation with a structure would become slower due to unnecessary indirect access, plus allocation of structures would generally be pushed out of the stack into a heap.
The architects of the language exchanged the polymorphism of structures for their effectiveness.
- Did not understand, in C # is slicing? The creator of the C ++ language, by the way, counts the same way :) - ixSci
- @ixSci: It would be if they allowed the inheritance of structures. - VladD
- Then you should rephrase the sentence, I think. Because Now it is built as if slicing in C # is. - ixSci
- @ixSci "This problem is called slicing, and it is present" - IT, i.e. problem. - andreycha
- oneThat is, rather than equality, but identity: two instances of the same type content are indistinguishable, and the reference type instance has its own identity. - VladD