This page is under construction.
Virtually all ambitious programming languages have internal inconsistencies. C# is no exception. Here are ones that I find surprising
or annoying:
- Strings are reference types but masquerade as values by making their contents constant. So deep assignments are simulated by invalidating the target reference and creating a new target string initialized with the source's contents. This inconsistency is probably needed in any shallow reference language for representations of strings and money and other entities that need to have value semantics. Note that the C++ programming language, unlike C# and Java, was designed from the ground up to support value semantics with user defined classes.
- Structs are value types, but may not behave consistently as value types. If a struct holds both a primitive field and a reference to a managed object (surprisingly allowed) then a copy of this struct instance results in a target struct with a unique value for the primitive field, but a reference to the source structs managed object, e.g., value fields are deep copied and reference fields are shallow copied. This isn't surprising - its the nature of value and reference types. What is surprising is that a value type is allowed to hold references at all.
- Delegates are reference types that are declared and used with syntax and behavior entirely different from all other reference types. At their heart, delegates form a chain of instances that each hold a pointer to a function that will be called when the delegate is invoked. That behavior is useful and necessary, but could have be achieved using the Command Pattern without any need to hide internal use of function pointers. Commands behave and are represented like any other reference type.
Conclusions for Inconsistencies:
The C# language is, on the surface, relatively simple. However, strings, structs, and delegates have syntax or semantics that are
not consistent with the design principles of the language.
- Strings are reference types that behave like value types.
- Structs are value types whose behavior is a mix of value and reference behaviors.
- Delegates are reference types that are declared and used in a fashion unlike any other C# reference type.