The C# language works seamlessly with the .NET Framework, so it should come as no surprise that the built-in data types available to you as a C# developer are also part of the .NET platform. For example, C# has a built-in string type that’s identical to the System.String class included in the .NET Framework. The string type supports various string manipulation operations such as concatenation. Table 2-1 describes the built-in data types that are part of the C# language, along with their equivalent .NET Framework types.
Although the C# types and the types found in the .NET Framework are equivalent, you should stick with using the C# names for these types. Your code will look cleaner and be easier to read. However, if you’re required to work with component developers who use other languages, you should keep Table 2-1 in mind, as it will aid in mapping types between languages.
The common type system is a specification that defines type usage in the .NET Framework common language runtime and is a key part of the .NET Framework. When you use a string in C#, you’re using the same string that a Visual Basic .NET developer uses. When you use a bool in C#, that’s the same BOOLEAN type used by Eiffel programmers. A big win for all .NET developers is the simplicity with which we can now share data and types, without the need for the specialized conversion layers required prior to .NET.
Another big advantage of the common type system is that the runtime can guarantee type safety for many of the .NET languages, including C#. This means that the runtime can guarantee that programs will execute safely, without accidentally overwriting memory addresses, corrupting the stack, or accidentally writing into random areas of memory.
Rules about how languages for the .NET platform such as C# should interact with each other are specified in the Common Language Specification (CLS). The CLS contains rules about how data types should be exposed and organized so that developers employing multiple languages can reuse data types. The CLS isn’t concerned with how your code is organized internally; it specifies only the behavior that’s publicly exposed. If you build a component that follows all of the CLS rules, your component is said to be CLS-compliant. If your code breaks any of the CLS rules, the component isn’t compliant and you might find that your component is unusable by programs written in languages other than the language used for your component.
CLS compliance is desirable, but it limits both the types that are exposed by your components and the way in which the components are exposed. Some programming languages don’t properly handle both signed and unsigned types of the same size. For that reason, most of the unsigned C# scalar data types, other than the byte type, aren’t CLS-compliant. Table 2-2 lists the primitive C# types and indicates whether each is CLS-compliant.