-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIndex.html
More file actions
481 lines (478 loc) · 38.2 KB
/
Index.html
File metadata and controls
481 lines (478 loc) · 38.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="Styles.css">
</head>
<body>
<nav id="navbar">
<header id="menuTittle">
<h2>C#</h2>
</header>
<ul class="nav-items">
<li><a href="#A_tour_of_the_C#_language" class="nav-link">A tour of the C# language</a></li>
<li><a href="#.NET_architecture" class="nav-link">.NET architecture</a></li>
<li><a href="#Hello_world" class="nav-link">Hello world</a></li>
<li><a href="#Types_and_variables" class="nav-link">Types and variables</a></li>
<li><a href="#Program_structure" class="nav-link">Program structure</a></li>
<li><a href="#Classes_and_objects" class="nav-link">Classes and objects</a></li>
<li><a href="#Type_parameters" class="nav-link">Type parameters</a></li>
<li><a href="#Base_classes" class="nav-link">Base classes</a></li>
<li><a href="#Structs" class="nav-link">Structs</a></li>
<li><a href="#Interfaces" class="nav-link">Interfaces</a></li>
<li><a href="#Enums" class="nav-link">Enums</a></li>
<li><a href="#Nullable_types" class="nav-link">Nullable types</a></li>
<li><a href="#Tuples" class="nav-link">Tuples</a></li>
</ul>
</nav>
<main id="main-doc">
<section class="main-section" id="A_tour_of_the_C#_language">
<header class="h2" >
A tour of the C# language
</header>
<article>
<p>C# (pronounced "See Sharp") is a modern, object-oriented, and type-safe programming language. C# enables developers to build many types of secure and robust applications that run in .NET. C# has its roots in the C family of languages and will be immediately familiar to C, C++, Java, and JavaScript programmers. This tour provides an overview of the major components of the language in C# 8 and earlier. If you want to explore the language through interactive examples, try the introduction to C# tutorials.</p>
<p>C# is an object-oriented, component-oriented programming language. C# provides language constructs to directly support these concepts, making C# a natural language in which to create and use software components. Since its origin, C# has added features to support new workloads and emerging software design practices. At its core, C# is an object-oriented language. You define types and their behavior.</p>
<p>Several C# features help create robust and durable applications. Garbage collection automatically reclaims memory occupied by unreachable unused objects. Nullable types guard against variables that don't refer to allocated objects. Exception handling provides a structured and extensible approach to error detection and recovery. Lambda expressions support functional programming techniques. Language Integrated Query (LINQ) syntax creates a common pattern for working with data from any source. Language support for asynchronous operations provides syntax for building distributed systems. C# has a unified type system. All C# types, including primitive types such as int and double, inherit from a single root object type. All types share a set of common operations. Values of any type can be stored, transported, and operated upon in a consistent manner. Furthermore, C# supports both user-defined reference types and value types. C# allows dynamic allocation of objects and in-line storage of lightweight structures. C# supports generic methods and types, which provide increased type safety and performance. C# provides iterators, which enable implementers of collection classes to define custom behaviors for client code.</p>
<p>C# emphasizes versioning to ensure programs and libraries can evolve over time in a compatible manner. Aspects of C#'s design that were directly influenced by versioning considerations include the separate virtual and override modifiers, the rules for method overload resolution, and support for explicit interface member declarations.</p>
</article>
</section>
<section class="main-section" id="Hello_world">
<header class="h2">
Hello world
</header>
<article>
<p>The "Hello, World" program is traditionally used to introduce a programming language. Here it is in C#:</p>
<pre>
<code>
using System;
class Hello
{
static void Main()
{
Console.WriteLine("Hello, World");
}
}
</code>
</pre>
<p>The "Hello, World" program starts with a using directive that references the System namespace. Namespaces provide a hierarchical means of organizing C# programs and libraries. Namespaces contain types and other namespaces—for example, the System namespace contains a number of types, such as the Console class referenced in the program, and a number of other namespaces, such as IO and Collections. A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.</p>
<p>The Hello class declared by the "Hello, World" program has a single member, the method named Main. The Main method is declared with the static modifier. While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. By convention, a static method named Main serves as the entry point of a C# program.</p>
<p>The output of the program is produced by the WriteLine method of the Console class in the System namespace. This class is provided by the standard class libraries, which, by default, are automatically referenced by the compiler.</p>
</article>
</section>
<section class="main-section" id=".NET_architecture">
<header class="h2">
.NET architecture
</header>
<article>
<p>C# programs run on .NET, a virtual execution system called the common language runtime (CLR) and a set of class libraries. The CLR is the implementation by Microsoft of the common language infrastructure (CLI), an international standard. The CLI is the basis for creating execution and development environments in which languages and libraries work together seamlessly.</p>
<p>Source code written in C# is compiled into an intermediate language (IL) that conforms to the CLI specification. The IL code and resources, such as bitmaps and strings, are stored in an assembly, typically with an extension of .dll. An assembly contains a manifest that provides information about the assembly's types, version, and culture.</p>
<p>When the C# program is executed, the assembly is loaded into the CLR. The CLR performs Just-In-Time (JIT) compilation to convert the IL code to native machine instructions. The CLR provides other services related to automatic garbage collection, exception handling, and resource management. Code that's executed by the CLR is sometimes referred to as "managed code." "Unmanaged code," is compiled into native machine language that targets a specific platform.</p>
<p>Language interoperability is a key feature of .NET. IL code produced by the C# compiler conforms to the Common Type Specification (CTS). IL code generated from C# can interact with code that was generated from the .NET versions of F#, Visual Basic, C++. There are more than 20 other CTS-compliant languages. A single assembly may contain multiple modules written in different .NET languages. The types can reference each other as if they were written in the same language.</p>
<p>In addition to the run time services, .NET also includes extensive libraries. These libraries support many different workloads. They're organized into namespaces that provide a wide variety of useful functionality. The libraries include everything from file input and output to string manipulation to XML parsing, to web application frameworks to Windows Forms controls. The typical C# application uses the .NET class library extensively to handle common "plumbing" chores.</p>
</article>
</section>
<section class="main-section" id="Types_and_variables">
<header class="h2">
Types and variables
</header>
<article>
<p>A type defines the structure and behavior of any data in C#. The declaration of a type may include its members, base type, interfaces it implements, and operations permitted for that type. A variable is a label that refers to an instance of a specific type.</p>
<p>There are two kinds of types in C#: value types and reference types. Variables of value types directly contain their data. Variables of reference types store references to their data, the latter being known as objects. With reference types, it's possible for two variables to reference the same object and possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it isn't possible for operations on one to affect the other (except for ref and out parameter variables).</p>
<p>An identifier is a variable name. An identifier is a sequence of unicode characters without any whitespace. An identifier may be a C# reserved word, if it's prefixed by @. Using a reserved word as an identifier can be useful when interacting with other languages.</p>
<p>C#'s value types are further divided into simple types, enum types, struct types, nullable value types, and tuple value types. C#'s reference types are further divided into class types, interface types, array types, and delegate types.</p>
<p>The following outline provides an overview of C#'s type system.</p>
<ul class="ulText">
<li>Value types</li>
<ul class="ulText">
<li>Simple types</li>
<ul class="ulText">
<li>Signed integral: sbyte, short, int, long</li>
<li>Unsigned integral: byte, ushort, uint, ulong</li>
<li>Unicode characters: char, which represents a UTF-16 code unit</li>
<li>IEEE binary floating-point: float, double</li>
<li>High-precision decimal floating-point: decimal</li>
<li>Boolean: bool, which represents Boolean values—values that are either true or false</li>
</ul>
<li>Enum types</li>
<ul class="ulText">
<li>User-defined types of the form enum E {...}. An enum type is a distinct type with named constants. Every enum type has an underlying type, which must be one of the eight integral types. The set of values of an enum type is the same as the set of values of the underlying type.</li>
</ul>
<li>Struct types</li>
<ul class="ulText">
<li>User-defined types of the form struct S {...}</li>
</ul>
<li>Nullable value types</li>
<ul class="ulText">
<li>Extensions of all other value types with a null value</li>
</ul>
<li>Tuple value types</li>
<ul class="ulText">
<li>User-defined types of the form (T1, T2, ...)</li>
</ul>
</ul>
<li>Reference types</li>
<ul class="ulText">
<li>Class types</li>
<li>Interface types</li>
<li>Array types</li>
<li>Delegate types</li>
</ul>
</ul>
<p>C# programs use type declarations to create new types. A type declaration specifies the name and the members of the new type. Six of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, delegate types, and tuple value types. You can also declare record types, either record struct, or record class. Record types have compiler-synthesized members. You use records primarily for storing values, with minimal associated behavior.</p>
<ul class="ulText">
<li>A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.</li>
<li>A struct type is similar to a class type in that it represents a structure with data members and function members. However, unlike classes, structs are value types and don't typically require heap allocation. Struct types don't support user-specified inheritance, and all struct types implicitly inherit from type object.</li>
<li>A struct type is similar to a class type in that it represents a structure with data members and function members. However, unlike classes, structs are value types and don't typically require heap allocation. Struct types don't support user-specified inheritance, and all struct types implicitly inherit from type object.</li>
<li>A delegate type represents references to methods with a particular parameter list and return type. Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Delegates are analogous to function types provided by functional languages. They're also similar to the concept of function pointers found in some other languages. Unlike function pointers, delegates are object-oriented and type-safe.</li>
</ul>
<p>The class, struct, interface, and delegate types all support generics, whereby they can be parameterized with other types.</p>
<p>C# supports single-dimensional and multi-dimensional arrays of any type. Unlike the types listed above, array types don't have to be declared before they can be used. Instead, array types are constructed by following a type name with square brackets. For example, int[] is a single-dimensional array of int, int[,] is a two-dimensional array of int, and int[][] is a single-dimensional array of single-dimensional arrays, or a "jagged" array, of int.</p>
<p>Nullable types don't require a separate definition. For each non-nullable type T, there's a corresponding nullable type T?, which can hold an additional value, null. For instance, int? is a type that can hold any 32-bit integer or the value null, and string? is a type that can hold any string or the value null.</p>
<p>C#'s type system is unified such that a value of any type can be treated as an object. Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Values of reference types are treated as objects simply by viewing the values as type object. Values of value types are treated as objects by performing boxing and unboxing operations. In the following example, an int value is converted to object and back again to int.</p>
<pre>
<code>
int i = 123;
object o = i; <span>// Boxing</span>
int j = (int)o; <span>// Unboxing</span>
</code>
</pre>
<p>When a value of a value type is assigned to an object reference, a "box" is allocated to hold the value. That box is an instance of a reference type, and the value is copied into that box. Conversely, when an object reference is cast to a value type, a check is made that the referenced object is a box of the correct value type. If the check succeeds, the value in the box is copied to the value type.</p>
<p>C#'s unified type system effectively means that value types are treated as object references "on demand." Because of the unification, general-purpose libraries that use type object can be used with all types that derive from object, including both reference types and value types.</p>
<p>There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. Variables represent storage locations. Every variable has a type that determines what values can be stored in the variable, as shown below.</p>
<ul class="ulText">
<li>Non-nullable value type</li>
<ul class="ulText">
<li>A value of that exact type</li>
</ul>
<li>Nullable value type</li>
<ul class="ulText">
<li>A null value or a value of that exact type</li>
</ul>
<li>object</li>
<ul class="ulText">
<li>A null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type</li>
</ul>
<li>Class type</li>
<ul class="ulText">
<li>A null reference, a reference to an instance of that class type, or a reference to an instance of a class derived from that class type</li>
</ul>
<li>Interface type</li>
<ul class="ulText">
<li>A null reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type</li>
</ul>
<li>Array type</li>
<ul class="ulText">
<li>A null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type</li>
</ul>
<li>Delegate type</li>
<ul class="ulText">
<li>A null reference or a reference to an instance of a compatible delegate type</li>
</ul>
</ul>
</article>
</section>
<section class="main-section" id="Program_structure">
<header class="h2">
Program structure
</header>
<article>
<p>The key organizational concepts in C# are programs, namespaces, types, members, and assemblies. Programs declare types, which contain members and can be organized into namespaces. Classes, structs, and interfaces are examples of types. Fields, methods, properties, and events are examples of members. When C# programs are compiled, they're physically packaged into assemblies. Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries, respectively.</p>
<p>As a small example, consider an assembly that contains the following code:</p>
<pre>
<code>
namespace Acme.Collections;
public class Stack<T></T>
{
Entry _top;
public void Push(T data)
{
_top = new Entry(_top, data);
}
public T Pop()
{
if (_top == null)
{
throw new InvalidOperationException();
}
T result = _top.Data;
_top = _top.Next;
return result;
}
class Entry
{
public Entry Next { get; set; }
public T Data { get; set; }
public Entry(Entry next, T data)
{
Next = next;
Data = data;
}
}
}
</code>
</pre>
<p>The fully qualified name of this class is Acme.Collections.Stack. The class contains several members: a field named _top, two methods named Push and Pop, and a nested class named Entry. The Entry class further contains three members: a property named Next, a property named Data, and a constructor. The Stack is a generic class. It has one type parameter, T that is replaced with a concrete type when it's used.</p>
<p>A stack is a "first in - last out" (FILO) collection. New elements are added to the top of the stack. When an element is removed, it's removed from the top of the stack. The previous example declares the Stack type that defines the storage and behavior for a stack. You can declare a variable that refers to an instance of the Stack type to use that functionality.</p>
<p>Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Before it's executed, the Just-In-Time (JIT) compiler of .NET Common Language Runtime converts the IL code in an assembly to processor-specific code.</p>
<p>Because an assembly is a self-describing unit of functionality containing both code and metadata, there's no need for #include directives and header files in C#. The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program. For example, this program uses the Acme.Collections.Stack class from the acme.dll assembly:</p>
<pre>
<code>
class Example
{
public static void Main()
{
var s = new Acme.Collections.Stack<int>();
s.Push(1); // stack contains 1
s.Push(10); // stack contains 1, 10
s.Push(100); // stack contains 1, 10, 100
Console.WriteLine(s.Pop()); <span>// stack contains 1, 10</span>
Console.WriteLine(s.Pop()); <span>// stack contains 1</span>
Console.WriteLine(s.Pop()); <span>// stack is empty</span>
}
}
</code>
</pre>
<p>To compile this program, you would need to reference the assembly containing the stack class defined in the earlier example.</p>
<p>C# programs can be stored in several source files. When a C# program is compiled, all of the source files are processed together, and the source files can freely reference each other. Conceptually, it's as if all the source files were concatenated into one large file before being processed. Forward declarations are never needed in C# because, with few exceptions, declaration order is insignificant. C# doesn't limit a source file to declaring only one public type nor does it require the name of the source file to match a type declared in the source file.</p>
<p>Further articles in this tour explain these organizational blocks.</p>
</article>
</section>
<section class="main-section" id="Classes_and_objects">
<header class="h2">
Classes and objects
</header>
<article>
<p>Classes are the most fundamental of C#'s types. A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. A class provides a definition for instances of the class, also known as objects. Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.</p>
<p>New classes are created using class declarations. A class declaration starts with a header. The header specifies:</p>
<ul>
<li>The attributes and modifiers of the class</li>
<li>The name of the class</li>
<li>The base class (when inheriting from a base class)</li>
<li>The interfaces implemented by the class.</li>
</ul>
<p>The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.</p>
<p>The following code shows a declaration of a simple class named Point:</p>
<pre>
<code>
public class Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
}
</code>
</pre>
<p>Instances of classes are created using the new operator, which allocates memory for a new instance, invokes a constructor to initialize the instance, and returns a reference to the instance. The following statements create two Point objects and store references to those objects in two variables:</p>
<pre>
<code>
var p1 = new Point(0, 0);
var p2 = new Point(10, 20);
</code>
</pre>
<p>The memory occupied by an object is automatically reclaimed when the object is no longer reachable. It's not necessary or possible to explicitly deallocate objects in C#.</p>
</article>
</section>
<section class="main-section" id="Type_parameters">
<header class="h2">
Type parameters
</header>
<article>
<p>Generic classes define type parameters. Type parameters are a list of type parameter names enclosed in angle brackets. Type parameters follow the class name. The type parameters can then be used in the body of the class declarations to define the members of the class. In the following example, the type parameters of Pair are TFirst and TSecond:</p>
<pre>
<code>
public class Pair<TFirst, TSecond></TFirst>
{
public TFirst First { get; }
public TSecond Second { get; }
public Pair(TFirst first, TSecond second) =>
First, Second) = (first, second);
}
</code>
</pre>
<p>A class type that is declared to take type parameters is called a generic class type. Struct, interface, and delegate types can also be generic. When the generic class is used, type arguments must be provided for each of the type parameters:</p>
<pre>
<code>
var pair = new Pair<int, string>(1, "two");
int i = pair.First; <span>//TFirst intspan</span>
string s = pair.Second; <span>//TSecond string</span>
</code>
</pre>
</article>
</section>
<section class="main-section" id="Base_classes">
<header class="h2">
Base classes
</header>
<article>
<p>A class declaration may specify a base class. Follow the class name and type parameters with a colon and the name of the base class. Omitting a base class specification is the same as deriving from type object. In the following example, the base class of Point3D is Point. From the first example, the base class of Point is object:</p>
<pre>
<code>
public class Point3D : Point
{
public int Z { get; set; }
public Point3D(int x, int y, int z) : base(x, y)
{
Z = z;
}
}
</code>
</pre>
<p>A class inherits the members of its base class. Inheritance means that a class implicitly contains almost all members of its base class. A class doesn't inherit the instance and static constructors, and the finalizer. A derived class can add new members to those members it inherits, but it can't remove the definition of an inherited member. In the previous example, Point3D inherits the X and Y members from Point, and every Point3D instance contains three properties, X, Y, and Z.</p>
<p>An implicit conversion exists from a class type to any of its base class types. A variable of a class type can reference an instance of that class or an instance of any derived class. For example, given the previous class declarations, a variable of type Point can reference either a Point or a Point3D:</p>
<pre>
<code>
Point a = new(10, 20);
Point b = new Point3D(10, 20, 30);
</code>
</pre>
</article>
</section>
<section class="main-section" id="Structs">
<header class="h2">
Structs
</header>
<article>
<p>Classes define types that support inheritance and polymorphism. They enable you to create sophisticated behaviors based on hierarchies of derived classes. By contrast, struct types are simpler types whose primary purpose is to store data values. Structs can't declare a base type; they implicitly derive from System.ValueType. You can't derive other struct types from a struct type. They're implicitly sealed.</p>
<pre>
<code>
public struct Point
{
double X { get; }
public double Y { get; }
public Point(double x, double y) => (X, Y) = (x, y);
}
</code>
</pre>
</article>
</section>
<section class="main-section" id="Interfaces">
<header class="h2">
Interfaces
</header>
<article>
<p>An interface defines a contract that can be implemented by classes and structs. You define an interface to declare capabilities that are shared among distinct types. For example, the System.Collections.Generic.IEnumerable<T> interface defines a consistent way to traverse all the items in a collection, such as an array. An interface can contain methods, properties, events, and indexers. An interface typically doesn't provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.</p>
<p>Interfaces may employ multiple inheritance. In the following example, the interface IComboBox inherits from both ITextBox and IListBox.</p>
<pre>
<code>
interface IControl
{
void Paint();
}
interface ITextBox : IControl
{
void SetText(string text);
}
interface IListBox : IControl
{
void SetItems(string[] items);
}
interface IComboBox : ITextBox, IListBox { }
</code>
</pre>
<p>Classes and structs can implement multiple interfaces. In the following example, the class EditBox implements both IControl and IDataBound.</p>
<pre>
<code>
interface IDataBound
{
void Bind(Binder b);
}
public class EditBox : IControl, IDataBound
{
public void Paint() { }
public void Bind(Binder b) { }
}
</code>
</pre>
<p>When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. For example</p>
<pre>
<code>
EditBox editBox = new();
IControl control = editBox;
IDataBound dataBound = editBox;
</code>
</pre>
</article>
</section>
<section class="main-section" id="Enums">
<header class="h2">
Enums
</header>
<article>
<p>An Enum type defines a set of constant values. The following enum declares constants that define different root vegetables:</p>
<pre>
<code>
public enum SomeRootVegetable
{
HorseRadish,
Radish,
Turnip
}
</code>
</pre>
<p>You can also define an enum to be used in combination as flags. The following declaration declares a set of flags for the four seasons. Any combination of the seasons may be applied, including an All value that includes all seasons:</p>
<pre>
<code>
[Flags]
public enum Seasons
{
None = 0,
Summer = 1,
Autumn = 2,
Winter = 4,
Spring = 8,
All = Summer | Autumn | Winter | Spring
}
</code>
</pre>
<p>The following example shows declarations of both the preceding enums:</p>
<pre>
<code>
var turnip = SomeRootVegetable.Turnip;
var spring = Seasons.Spring;
var startingOnEquinox = Seasons.Spring | Seasons.Autumn;
var theYear = Seasons.All;
</code>
</pre>
</article>
</section>
<section class="main-section" id="Nullable_types">
<header class="h2">
Nullable types
</header>
<article>
<p>Variables of any type may be declared as non-nullable or nullable. A nullable variable can hold an additional null value, indicating no value. Nullable Value types (structs or enums) are represented by System.Nullable<T>. Non-nullable and Nullable Reference types are both represented by the underlying reference type. The distinction is represented by metadata read by the compiler and some libraries. The compiler provides warnings when nullable references are dereferenced without first checking their value against null. The compiler also provides warnings when non-nullable references are assigned a value that may be null. The following example declares a nullable int, initializing it to null. Then, it sets the value to 5. It demonstrates the same concept with a nullable string. For more information, see nullable value types and nullable reference types.</p>
<pre>
<code>
int? optionalInt = default;
optionalInt = 5;
string? optionalText = default;
optionalText = "Hello World.";
</code>
</pre>
</article>
</section>
<section class="main-section" id="Tuples">
<header class="h2">
Tuples
</header>
<article>
<p>C# supports tuples, which provides concise syntax to group multiple data elements in a lightweight data structure. You instantiate a tuple by declaring the types and names of the members between ( and ), as shown in the following</p>
<p>example:</p>
<pre>
<code>
(double Sum, int Count) t2 = (4.5, 3);
Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
<span>//Output:</span>
<span>//Sum of 3 elements is 4.5.</span>
</code>
</pre>
<p>Tuples provide an alternative for data structure with multiple members, without using the building blocks described in the next article.</p>
</article>
</section>
</main>
</body>
</html>