Skip to content

Basic types, classes and structs #1134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 72 additions & 14 deletions docs/csharp/basic-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,84 @@
title: Basic Types | C# Guide
description: Learn about the core types (numerics, strings, and object) in all C# programs
keywords: .NET, .NET Core, C#
author: dotnet-bot
author: stevehoag
manager: wpickett
ms.date: 06/25/2016
ms.date: 10/10/2016
ms.topic: article
ms.prod: .net-core
ms.technology: .net-core-technologies
ms.devlang: csharp
ms.assetid: 95c686ba-ae4f-440e-8e94-0dbd6e04d11f
---

# 🔧 Basic Types
# Types, variables, and values
C# is a strongly-typed language. Every variable and constant has a type, as does every expression that evaluates to a value. Every method signature specifies a type for each input parameter and for the return value. The .NET Framework class library defines a set of built-in numeric types as well as more complex types that represent a wide variety of logical constructs, such as the file system, network connections, collections and arrays of objects, and dates. A typical C# program uses types from the class library as well as user-defined types that model the concepts that are specific to the program's problem domain.

The information stored in a type can include the following:

- The storage space that a variable of the type requires.

- The maximum and minimum values that it can represent.

- The members (methods, fields, events, and so on) that it contains.

- The base type it inherits from.

- The location where the memory for variables will be allocated at run time.

- The kinds of operations that are permitted.

The compiler uses type information to make sure that all operations that are performed in your code are *type safe*. For example, if you declare a variable of type [int](https://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx), the compiler allows you to use the variable in addition and subtraction operations. If you try to perform those same operations on a variable of type [bool](https://msdn.microsoft.com/en-us/library/c8f5xwh7.aspx), the compiler generates an error, as shown in the following example:

[!code-csharp[Type Safety](../../samples/snippets/csharp/concepts/basic-types/type-safety.cs)]

> [!NOTE]
> C and C++ developers, notice that in C#, [bool](https://msdn.microsoft.com/en-us/library/c8f5xwh7.aspx) is not convertible to [int](https://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx).

The compiler embeds the type information into the executable file as metadata. The common language runtime (CLR) uses that metadata at run time to further guarantee type safety when it allocates and reclaims memory.

> **Note**
>
> This topic hasn’t been written yet!
>
> We welcome your input to help shape the scope and approach. You can track the status and provide input on this
> [issue](https://github.com/dotnet/core-docs/issues/963) at GitHub.
>
> If you would like to review early drafts and outlines of this topic, please leave a note with your contact information in the issue.
>
> Learn more about how you can contribute on [GitHub](https://github.com/dotnet/core-docs/blob/master/CONTRIBUTING.md).
>
## Specifying types in variable declarations
When you declare a variable or constant in a program, you must either specify its type or use the [var](https://msdn.microsoft.com/en-us/library/bb383973.aspx) keyword to let the compiler infer the type. The following example shows some variable declarations that use both built-in numeric types and complex user-defined types:

[!code-csharp[Variable Declaration](../../samples/snippets/csharp/concepts/basic-types/variable-declaration.cs)]

The types of method parameters and return values are specified in the method signature. The following signature shows a method that requires an [int](https://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx) as an input argument and returns a string:

[!code-csharp[Method Signature](../../samples/snippets/csharp/concepts/basic-types/method-signature.cs)]

After a variable is declared, it cannot be re-declared with a new type, and it cannot be assigned a value that is not compatible with its declared type. For example, you cannot declare an [int](https://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx) and then assign it a Boolean value of [true](https://msdn.microsoft.com/en-us/library/06d3w013.aspx). However, values can be converted to other types, for example when they are assigned to new variables or passed as method arguments. A *type conversion* that does not cause data loss is performed automatically by the compiler. A conversion that might cause data loss requires a *cast* in the source code.

For more information, see [Casting and type conversions](https://msdn.microsoft.com/en-us/library/ms173105.aspx).

## Built-in types
C# provides a standard set of built-in numeric types to represent integers, floating point values, Boolean expressions, text characters, decimal values, and other types of data. There are also built-in **string** and **object** types. These are available for you to use in any C# program. For a more information about the built-in types, see [Types reference tables](https://msdn.microsoft.com/en-us/library/1dhd7f2x.aspx).

## Custom types
You use the [struct](https://msdn.microsoft.com/en-us/library/ah19swz4.aspx), [class](https://msdn.microsoft.com/en-us/library/0b0thckt.aspx), [interface](https://msdn.microsoft.com/en-us/library/87d83y5b.aspx), and [enum](https://msdn.microsoft.com/en-us/library/sbbt4032.aspx) constructs to create your own custom types. The .NET Framework class library itself is a collection of custom types provided by Microsoft that you can use in your own applications. By default, the most frequently used types in the class library are available in any C# program. Others become available only when you explicitly add a project reference to the assembly in which they are defined. After the compiler has a reference to the assembly, you can declare variables (and constants) of the types declared in that assembly in source code. For more information, see [.NET Framework class library](https://msdn.microsoft.com/en-us/library/gg145045(v=vs.110).aspx).

## Generic types
A type can be declared with one or more *type parameters* that serve as a placeholder for the actual type (the *concrete type*) that client code will provide when it creates an instance of the type. Such types are called *generic types*. For example, the .NET Framework type @System.Collections.Generic.List%601 has one type parameter that by convention is given the name *T*. When you create an instance of the type, you specify the type of the objects that the list will contain, for example, string:

[!code-csharp[Generic types](../../samples/snippets/csharp/concepts/basic-types/generic-type.cs)]

The use of the type parameter makes it possible to reuse the same class to hold any type of element, without having to convert each element to [object](https://msdn.microsoft.com/en-us/library/9kkx3h3c.aspx). Generic collection classes are called *strongly-typed collections* because the compiler knows the specific type of the collection's elements and can raise an error at compile-time if, for example, you try to add an integer to the `strings` object in the previous example. For more information, see [Generics](generics.md).

## Implicit types, anonymous types, and tuple types
As stated previously, you can implicitly type a local variable (but not class members) by using the [var](https://msdn.microsoft.com/en-us/library/bb383973.aspx) keyword. The variable still receives a type at compile time, but the type is provided by the compiler. For more information, see [Implicitly typed local variables](https://msdn.microsoft.com/en-us/library/bb384061.aspx).

In some cases, it is inconvenient to create a named type for simple sets of related values that you do not intend to store or pass outside method boundaries. You can create *anonymous types* for this purpose. For more information, see [Anonymous types](https://msdn.microsoft.com/en-us/library/bb397696.aspx).

It's common to want to return more than one value from a method. You can create *tuple types* that return multiple values in a single method call. For more information, see [Tuples](tuples.md)

## The Common type system
It is important to understand two fundamental points about the type system in the .NET Framework:

- It supports the principle of inheritance. Types can derive from other types, called *base types*. The derived type inherits (with some restrictions) the methods, properties, and other members of the base type. The base type can in turn derive from some other type, in which case the derived type inherits the members of both base types in its inheritance hierarchy. All types, including built-in numeric types such as @System.Int32 (C# keyword: `int`), derive ultimately from a single base type, which is @System.Object (C# keyword: `object`). This unified type hierarchy is called the [Common type system](../standard/common-type-system.md) (CTS). For more information about inheritance in C#, see [Inheritance](https://msdn.microsoft.com/en-us/library/ms173149.aspx).

- Each type in the CTS is defined as either a *value type* or a *reference type*. This includes all custom types in the .NET Framework class library and also your own user-defined types. Types that you define by using the [struct](https://msdn.microsoft.com/en-us/library/ah19swz4.aspx) keyword are value types; all the built-in numeric types are **structs**. For more information about value types, see [Structs](structs.md). Types that you define by using the [class](https://msdn.microsoft.com/en-us/library/0b0thckt.aspx) keyword are reference types. For more information about reference types, see [Classes](classes.md). Reference types and value types have different compile-time rules, and different run-time behavior.


## See also
[Structs](structs.md)

[Classes](classes.md)
82 changes: 68 additions & 14 deletions docs/csharp/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,80 @@
title: Classes | C# Guide
description: Learn about the class types and how you create them
keywords: .NET, .NET Core, C#
author: dotnet-bot
author: stevehoag
manager: wpickett
ms.date: 06/25/2016
ms.date: 10/10/2016
ms.topic: article
ms.prod: .net-core
ms.technology: .net-core-technologies
ms.devlang: csharp
ms.assetid: 95c686ba-ae4f-440e-8e94-0dbd6e04d11f
---

# 🔧 Classes
# Classes
A *class* is a construct that enables you to create your own custom types by grouping together variables of other types, methods and events. A class is like a blueprint. It defines the data and behavior of a type. If the class is not declared as static, client code can use it by creating *objects* or *instances* which are assigned to a variable. The variable remains in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for garbage collection. If the class is declared as [static](https://msdn.microsoft.com/en-us/library/98f28cdx.aspx), then only one copy exists in memory and client code can only access it through the class itself, not an *instance variable*. For more information, see [Static classes and static class members](https://msdn.microsoft.com/en-us/library/79b3xss3.aspx).

## Reference types
A type that is defined as a [class](https://msdn.microsoft.com/en-us/library/0b0thckt.aspx) is a *reference type*. At run time, when you declare a variable of a reference type, the variable contains the value [null](https://msdn.microsoft.com/en-us/library/edakx9da.aspx) until you explicitly create an instance of the object by using the [new](https://msdn.microsoft.com/en-us/library/51y09td4.aspx) operator, or assign it an object that has been created elsewhere by using [new](https://msdn.microsoft.com/en-us/library/51y09td4.aspx), as shown in the following example:

[!code-csharp[Reference Types](../../samples/snippets/csharp/concepts/classes/reference-type.cs)]

When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference to the location of the object. Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as *garbage collection*. However, garbage collection is also highly optimized, and in most scenarios, it does not create a performance issue. For more information about garbage collection, see [Automatic memory management and garbage collection](../standard/garbagecollection/gc.md).

Reference types fully support *inheritance*, a fundamental characteristic of object-oriented programming. When you create a class, you can inherit from any other interface or class that is not defined as [sealed](https://msdn.microsoft.com/en-us/library/88c54tsw.aspx), and other classes can inherit from your class and override your virtual methods. For more information, see [Inheritance](https://msdn.microsoft.com/en-us/library/ms173149.aspx).

## Declaring classes
Classes are declared by using the [class](https://msdn.microsoft.com/en-us/library/0b0thckt.aspx) keyword, as shown in the following example:

[!code-csharp[Declaring Classes](../../samples/snippets/csharp/concepts/classes/declaring-classes.cs)]

The **class** keyword is preceded by the access modifier. Because [public](https://msdn.microsoft.com/en-us/library/yzh058ae.aspx) is used in this case, anyone can create objects from this class. The name of the class follows the **class** keyword. The remainder of the definition is the class body, where the behavior and data are defined. Fields, properties, methods, and events on a class are collectively referred to as *class members*.

## Creating objects
A class defines a type of object, but it is not an object itself. An object is a concrete entity based on a class, and is sometimes referred to as an instance of a class.

Objects can be created by using the [new](https://msdn.microsoft.com/en-us/library/51y09td4.aspx) keyword followed by the name of the class that the object will be based on, like this:

[!code-csharp[Creating Objects](../../samples/snippets/csharp/concepts/classes/creating-objects.cs)]

When an instance of a class is created, a reference to the object is passed back to the programmer. In the previous example, `object1` is a reference to an object that is based on `Customer`. This reference refers to the new object but does not contain the object data itself. In fact, you can create an object reference without creating an object at all:

[!code-csharp[Creating Objects](../../samples/snippets/csharp/concepts/classes/creating-objects2.cs)]

We do not recommend creating object references such as this one that does not refer to an object because trying to access an object through such a reference will fail at run time. However, such a reference can be made to refer to an object, either by creating a new object, or by assigning it to an existing object, such as this:

[!code-csharp[Creating Objects](../../samples/snippets/csharp/concepts/classes/creating-objects3.cs)]

This code creates two object references that both refer to the same object. Therefore, any changes to the object made through `object3` will be reflected in subsequent uses of `object4`. Because objects that are based on classes are referred to by reference, classes are known as reference types.

## Class inheritance
Inheritance is accomplished by using a *derivation*, which means a class is declared by using a *base class* from which it inherits data and behavior. A base class is specified by appending a colon and the name of the base class following the derived class name, like this:

[!code-csharp[Inheritance](../../samples/snippets/csharp/concepts/classes/inheritance.cs)]

When a class declares a base class, it inherits all the members of the base class except the constructors.

Unlike C++, a class in C# can only directly inherit from one base class. However, because a base class may itself inherit from another class, a class may indirectly inherit multiple base classes. Furthermore, a class can directly implement more than one interface. For more information, see [Interfaces](interfaces.md).

A class can be declared [abstract](https://msdn.microsoft.com/en-us/library/sf985hc5.aspx). An abstract class contains abstract methods that have a signature definition but no implementation. Abstract classes cannot be instantiated. They can only be used through derived classes that implement the abstract methods. By contrast, a [sealed](https://msdn.microsoft.com/en-us/library/88c54tsw.aspx) class does not allow other classes to derive from it. For more information, see [Abstract and sealed classes and class members](https://msdn.microsoft.com/en-us/library/ms173150.aspx).

Class definitions can be split between different source files. For more information, see [Partial class definitions](https://msdn.microsoft.com/en-us/library/wa80x488.aspx).


## Example
In the following example, a public class that contains a single field, a method, and a special method called a constructor is defined. For more information, see [Constructors](https://msdn.microsoft.com/en-us/library/ace5hbzh.aspx). The class is then instantiated with the **new** keyword.

[!code-csharp[Class Example](../../samples/snippets/csharp/concepts/classes/class-example.cs)]

## C# language specification
For more information, see the [C# language specification](https://msdn.microsoft.com/en-us/library/ms228593.aspx). The language specification is the definitive source for C# syntax and usage.

## See also
[C# programming guide](https://msdn.microsoft.com/en-us/library/67ef8sbd.aspx)
[Polymorphism](https://msdn.microsoft.com/en-us/library/ms173152.aspx)
[Class and struct members](https://msdn.microsoft.com/en-us/library/ms173113.aspx)
[Class and struct methods](https://msdn.microsoft.com/en-us/library/ms173114.aspx)
[Constructors](https://msdn.microsoft.com/en-us/library/ace5hbzh.aspx)
[Destructors](https://msdn.microsoft.com/en-us/library/66x5fx1b.aspx)
[Objects](https://msdn.microsoft.com/en-us/library/ms173110.aspx)

> **Note**
>
> This topic hasn’t been written yet!
>
> We welcome your input to help shape the scope and approach. You can track the status and provide input on this
> [issue](https://github.com/dotnet/core-docs/issues/964) at GitHub.
>
> If you would like to review early drafts and outlines of this topic, please leave a note with your contact information in the issue.
>
> Learn more about how you can contribute on [GitHub](https://github.com/dotnet/core-docs/blob/master/CONTRIBUTING.md).
>
Loading