Paseo por el lenguaje C#A tour of the C# language

C# (pronunciado "si sharp" en inglés) es un lenguaje de programación moderno, basado en objetos y con seguridad de tipos.C# (pronounced "See Sharp") is a modern, object-oriented, and type-safe programming language. que permite a los desarrolladores crear muchos tipos de aplicaciones seguras y sólidas que se ejecutan en el ecosistema de .NET.C# enables developers to build many types of secure and robust applications that run in the .NET ecosystem. C# tiene sus raíces en la familia de lenguajes C, y a los programadores de C, C++, Java y JavaScript les resultará familiar inmediatamente.C# has its roots in the C family of languages and will be immediately familiar to C, C++, Java, and JavaScript programmers. Este paseo proporciona información general de los principales componentes del lenguaje en C# 8 y versiones anteriores.This tour provides an overview of the major components of the language in C# 8 and earlier. Si quiere explorar el lenguaje a través de ejemplos interactivos, pruebe los tutoriales de introducción a C#.If you want to explore the language through interactive examples, try the introduction to C# tutorials.

C# es un lenguaje de programación *orientado a componentes _, orientado a objetos.C# is an object-oriented, *component-oriented _ programming language. C# proporciona construcciones de lenguaje para admitir directamente estos conceptos, por lo que se trata de un lenguaje natural en el que crear y usar componentes de software.C# provides language constructs to directly support these concepts, making C# a natural language in which to create and use software components. Desde su origen, C# ha agregado características para admitir nuevas cargas de trabajo y prácticas de diseño de software emergentes.Since its origin, C# has added features to support new workloads and emerging software design practices.

Varias características de C# facilitan la creación de aplicaciones sólidas y duraderas.Several C# features help create robust and durable applications. La recolección de elementos no utilizados reclama de forma automática la memoria ocupada por objetos no utilizados inalcanzables.Garbage collection automatically reclaims memory occupied by unreachable unused objects. Los tipos que aceptan valores NULL ofrecen protección ante variables que no hacen referencia a objetos asignados.Nullable types guard against variables that don't refer to allocated objects. El control de excepciones proporciona un enfoque estructurado y extensible para la detección y recuperación de errores.Exception handling provides a structured and extensible approach to error detection and recovery. Las expresiones lambda admiten técnicas de programación funcional.Lambda expressions support functional programming techniques. La sintaxis de Language Integrated Query (LINQ) crea un patrón común para trabajar con datos de cualquier origen.Language Integrated Query (LINQ) syntax creates a common pattern for working with data from any source. La compatibilidad del lenguaje con las operaciones asincrónicas proporciona la sintaxis para crear sistemas distribuidos.Language support for asynchronous operations provides syntax for building distributed systems. C# tiene un sistema de tipos unificados.C# has a unified type system. Todos los tipos de C#, incluidos los tipos primitivos como int y double, se heredan de un único tipo object raíz.All C# types, including primitive types such as int and double, inherit from a single root object type. Todos los tipos comparten un conjunto de operaciones comunes.All types share a set of common operations. Los valores de cualquier tipo se pueden almacenar, transportar y operar de forma coherente.Values of any type can be stored, transported, and operated upon in a consistent manner. Además, C# admite tanto tipos de referencia definidos por el usuario como tipos de valor.Furthermore, C# supports both user-defined reference types and value types. C# permite la asignación dinámica de objetos y el almacenamiento en línea de estructuras ligeras.C# allows dynamic allocation of objects and in-line storage of lightweight structures. C# admite métodos y tipos genéricos, que proporcionan una mayor seguridad de tipos, así como un mejor rendimiento.C# supports generic methods and types, which provide increased type safety and performance. C# también proporciona iteradores, gracias a los que los implementadores de clases de colecciones pueden definir comportamientos personalizados para el código de cliente.C# provides iterators, which enable implementers of collection classes to define custom behaviors for client code.

C# resalta el control de versiones para garantizar que los programas y las bibliotecas puedan evolucionar con el tiempo de manera compatible.C# emphasizes versioning to ensure programs and libraries can evolve over time in a compatible manner. Los aspectos del diseño de C# afectados directamente por las consideraciones de versionamiento incluyen los modificadores virtual y override independientes, las reglas para la resolución de sobrecargas de métodos y la compatibilidad para declaraciones explícitas de miembros de interfaz.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.

Arquitectura de .NET.NET architecture

Los programas de C# se ejecutan en .NET, un sistema de ejecución virtual denominado Common Language Runtime (CLR) y un conjunto de bibliotecas de clases.C# programs run on .NET, a virtual execution system called the common language runtime (CLR) and a set of class libraries. CLR es la implementación de Microsoft del estándar internacional Common Language Infrastructure (CLI).The CLR is the implementation by Microsoft of the common language infrastructure (CLI), an international standard. CLI es la base para crear entornos de ejecución y desarrollo en los que los lenguajes y las bibliotecas funcionan juntos sin problemas.The CLI is the basis for creating execution and development environments in which languages and libraries work together seamlessly.

El código fuente escrito en C# se compila en un lenguaje intermedio (IL) que guarda conformidad con la especificación de CLI.Source code written in C# is compiled into an intermediate language (IL) that conforms to the CLI specification. El código y los recursos de IL, como los mapas de bits y las cadenas, se almacenan en un ensamblado, normalmente con una extensión _.dll*.The IL code and resources, such as bitmaps and strings, are stored in an assembly, typically with an extension of _.dll*. Un ensamblado contiene un manifiesto que proporciona información sobre los tipos, la versión y la referencia cultural.An assembly contains a manifest that provides information about the assembly's types, version, and culture.

Cuando se ejecuta el programa C#, el ensamblado se carga en CLR.When the C# program is executed, the assembly is loaded into the CLR. CLR realiza la compilación Just-In-Time (JIT) para convertir el código IL en instrucciones de máquina nativas.The CLR performs Just-In-Time (JIT) compilation to convert the IL code to native machine instructions. Además, CLR proporciona otros servicios relacionados con la recolección de elementos no utilizados, el control de excepciones y la administración de recursos.The CLR provides other services related to automatic garbage collection, exception handling, and resource management. El código que se ejecuta en el CLR se conoce a veces como "código administrado", a diferencia del "código no administrado", que se compila en un lenguaje nativo de la máquina destinado a un sistema específico.Code that's executed by the CLR is sometimes referred to as "managed code," in contrast to "unmanaged code," which is compiled into native machine language that targets a specific platform.

La interoperabilidad entre lenguajes es una característica principal de .NET.Language interoperability is a key feature of .NET. El código IL generado por el compilador de C# se ajusta a la especificación de tipo común (CTS).IL code produced by the C# compiler conforms to the Common Type Specification (CTS). El código IL generado desde C# puede interactuar con el código generado a partir de las versiones de .NET de F# , Visual Basic, C++ o cualquiera de los más de 20 lenguajes compatibles con CTS.IL code generated from C# can interact with code that was generated from the .NET versions of F#, Visual Basic, C++, or any of more than 20 other CTS-compliant languages. Un solo ensamblado puede contener varios módulos escritos en diferentes lenguajes .NET y los tipos se pueden hacer referencia mutuamente igual que si estuvieran escritos en el mismo lenguaje.A single assembly may contain multiple modules written in different .NET languages, and the types can reference each other as if they were written in the same language.

Además de los servicios en tiempo de ejecución, .NET también incluye amplias bibliotecas,In addition to the run time services, .NET also includes extensive libraries. que admiten muchas cargas de trabajo diferentes.These libraries support many different workloads. Se organizan en espacios de nombres que proporcionan una gran variedad de funciones útiles para todo, desde la entrada y salida de archivos, la manipulación de cadenas y el análisis de XML hasta los marcos de aplicaciones web y los controles de Windows Forms.They're organized into namespaces that provide a wide variety of useful functionality for everything from file input and output to string manipulation to XML parsing, to web application frameworks to Windows Forms controls. En una aplicación de C# típica se usa la biblioteca de clases de .NET de forma extensa para controlar tareas comunes de infraestructura.The typical C# application uses the .NET class library extensively to handle common "plumbing" chores.

Para obtener más información sobre .NET, vea Introducción a .NET.For more information about .NET, see Overview of .NET.

Hola a todosHello world

El programa "Hola mundo" tradicionalmente se usa para presentar un lenguaje de programación.The "Hello, World" program is traditionally used to introduce a programming language. En este caso, se usa C#:Here it is in C#:

using System;

class Hello
{
    static void Main()
    {
        Console.WriteLine("Hello, World");
    }
}

El programa "Hola mundo" empieza con una directiva using que hace referencia al espacio de nombres System.The "Hello, World" program starts with a using directive that references the System namespace. Los espacios de nombres proporcionan un método jerárquico para organizar las bibliotecas y los programas de C#.Namespaces provide a hierarchical means of organizing C# programs and libraries. Los espacios de nombres contienen tipos y otros espacios de nombres; por ejemplo, el espacio de nombres System contiene varios tipos, como la clase Console a la que se hace referencia en el programa, y otros espacios de nombres, como IO y Collections.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. Una directiva using que hace referencia a un espacio de nombres determinado permite el uso no calificado de los tipos que son miembros de ese espacio de nombres.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. Debido a la directiva using, puede utilizar el programa Console.WriteLine como abreviatura de System.Console.WriteLine.Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

La clase Hello declarada por el programa "Hola mundo" tiene un miembro único, el método llamado Main.The Hello class declared by the "Hello, World" program has a single member, the method named Main. El método Main se declara con el modificador static.The Main method is declared with the static modifier. Mientras que los métodos de instancia pueden hacer referencia a una instancia de objeto envolvente determinada utilizando la palabra clave this, los métodos estáticos funcionan sin referencia a un objeto determinado.While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. Por convención, un método estático denominado Main sirve como punto de entrada de un programa de C#.By convention, a static method named Main serves as the entry point of a C# program.

La salida del programa la genera el método WriteLine de la clase Console en el espacio de nombres System.The output of the program is produced by the WriteLine method of the Console class in the System namespace. Esta clase la proporcionan las bibliotecas de clase estándar, a las que, de forma predeterminada, el compilador hace referencia automáticamente.This class is provided by the standard class libraries, which, by default, are automatically referenced by the compiler.

Tipos y variablesTypes and variables

Hay dos clases de tipos en C#: tipos de valor y tipos de referencia.There are two kinds of types in C#: value types and reference types. Las variables de tipos de valor contienen directamente sus datos.Variables of value types directly contain their data. Las variables de tipos de referencia almacenan referencias a los datos, lo que se conoce como objetos.Variables of reference types store references to their data, the latter being known as objects. Con los tipos de referencia, es posible que dos variables hagan referencia al mismo objeto y que, por tanto, las operaciones en una variable afecten al objeto al que hace referencia la otra.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. Con los tipos de valor, cada variable tiene su propia copia de los datos y no es posible que las operaciones en una variable afecten a la otra (excepto para las variables de parámetro ref y out).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).

Un *identificador _ es un nombre de variable.An *identifier _ is a variable name. Un identificador es una secuencia de caracteres Unicode sin ningún espacio en blanco.An identifier is a sequence of unicode characters without any whitespace. Un identificador puede ser una palabra reservada de C# si tiene el prefijo @.An identifier may be a C# reserved word, if it's prefixed by @. El uso de una palabra reservada como identificador puede ser útil al interactuar con otros lenguajes.Using a reserved word as an identifier can be useful when interacting with other languages.

Los tipos de valor de C# se dividen en _tipos simples*, tipos de enumeración, tipos de estructura, tipos de valor que aceptan valores NULL y tipos de valor de tupla.C#'s value types are further divided into _simple types*, enum types, struct types, nullable value types, and tuple value types. Los tipos de referencia de C# se dividen en tipos de clase, tipos de interfaz, tipos de matriz y tipos delegados.C#'s reference types are further divided into class types, interface types, array types, and delegate types.

En el esquema siguiente se ofrece información general del sistema de tipos de C#.The following outline provides an overview of C#'s type system.

Los programas de C# utilizan declaraciones de tipos para crear nuevos tipos.C# programs use type declarations to create new types. Una declaración de tipos especifica el nombre y los miembros del nuevo tipo.A type declaration specifies the name and the members of the new type. Seis de las categorías de tipos de C# las define el usuario: tipos de clase, tipos de estructura, tipos de interfaz, tipos de enumeración, tipos de delegado y tipos de valor de tupla.Six of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, delegate types, and tuple value types.

  • A tipo class define una estructura de datos que contiene miembros de datos (campos) y miembros de función (métodos, propiedades y otros).A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Los tipos de clase admiten herencia única y polimorfismo, mecanismos por los que las clases derivadas pueden extender y especializar clases base.Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.
  • Un tipo struct es similar a un tipo de clase, por el hecho de que representa una estructura con miembros de datos y miembros de función.A struct type is similar to a class type in that it represents a structure with data members and function members. Pero a diferencia de las clases, las estructuras son tipos de valor y no suelen requerir la asignación del montón.However, unlike classes, structs are value types and don't typically require heap allocation. Los tipos de estructura no admiten la herencia especificada por el usuario y todos se heredan implícitamente del tipo object.Struct types don't support user-specified inheritance, and all struct types implicitly inherit from type object.
  • Un tipo interface define un contrato como un conjunto con nombre de miembros públicos.An interface type defines a contract as a named set of public members. Un valor class o struct que implementa interface debe proporcionar implementaciones de miembros de la interfaz.A class or struct that implements an interface must provide implementations of the interface's members. Un interface puede heredar de varias interfaces base, y un class o struct pueden implementar varias interfaces.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.
  • Un tipo delegate representa las referencias a métodos con una lista de parámetros determinada y un tipo de valor devuelto.A delegate type represents references to methods with a particular parameter list and return type. Los delegados permiten tratar métodos como entidades que se puedan asignar a variables y se puedan pasar como parámetros.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Los delegados son análogos a los tipos de función proporcionados por los lenguajes funcionales.Delegates are analogous to function types provided by functional languages. También son similares al concepto de punteros de función de otros lenguajes.They're also similar to the concept of function pointers found in some other languages. A diferencia de los punteros de función, los delegados están orientados a objetos y tienen seguridad de tipos.Unlike function pointers, delegates are object-oriented and type-safe.

Los tipos class, struct, interface y delegate admiten parámetros genéricos, mediante los que se pueden parametrizar con otros tipos.The class, struct, interface, and delegate types all support generics, whereby they can be parameterized with other types.

C# admite matrices unidimensionales y multidimensionales de cualquier tipo.C# supports single-dimensional and multi-dimensional arrays of any type. A diferencia de los tipos enumerados antes, no es necesario declarar los tipos de matriz antes de usarlos.Unlike the types listed above, array types don't have to be declared before they can be used. En su lugar, los tipos de matriz se crean mediante un nombre de tipo entre corchetes.Instead, array types are constructed by following a type name with square brackets. Por ejemplo, int[] es una matriz unidimensional de int, int[,] es una matriz bidimensional de int y int[][] es una matriz unidimensional de las matrices unidimensionales, o la matriz "escalonada", de int.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.

Los tipos que aceptan valores NULL no requieren una definición independiente.Nullable types don't require a separate definition. Para cada tipo T que no acepta valores NULL, existe un tipo T? que acepta valores NULL correspondiente, que puede tener un valor adicional, null.For each non-nullable type T, there's a corresponding nullable type T?, which can hold an additional value, null. Por ejemplo, int? es un tipo que puede contener cualquier entero de 32 bits o el valor null y string? es un tipo que puede contener cualquier string o el valor 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.

El sistema de tipos de C# está unificado, de tal forma que un valor de cualquier tipo puede tratarse como object.C#'s type system is unified such that a value of any type can be treated as an object. Todos los tipos de C# directa o indirectamente se derivan del tipo de clase object, y object es la clase base definitiva de todos los tipos.Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Los valores de tipos de referencia se tratan como objetos mediante la visualización de los valores como tipo object.Values of reference types are treated as objects simply by viewing the values as type object. Los valores de tipos de valor se tratan como objetos mediante la realización de operaciones de conversión boxing y operaciones de conversión unboxing.Values of value types are treated as objects by performing boxing and unboxing operations. En el ejemplo siguiente, un valor int se convierte en object y vuelve a int.In the following example, an int value is converted to object and back again to int.

int i = 123;
object o = i;    // Boxing
int j = (int)o;  // Unboxing

Cuando se asigna un valor de un tipo de valor a una referencia object, se asigna un "box" para contener el valor.When a value of a value type is assigned to an object reference, a "box" is allocated to hold the value. Ese box es una instancia de un tipo de referencia, y es donde se copia el valor.That box is an instance of a reference type, and the value is copied into that box. Por el contrario, cuando una referencia object se convierte en un tipo de valor, se comprueba si el elemento object al que se hace referencia es un box del tipo de valor correcto.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. Si la comprobación se realiza correctamente, el valor del box se copia en el tipo de valor.If the check succeeds, the value in the box is copied to the value type.

El sistema de tipos unificado de C# conlleva efectivamente que los tipos de valor se tratan como referencias object "a petición".C#'s unified type system effectively means that value types are treated as object references "on demand." Debido a la unificación, las bibliotecas de uso general que utilizan el tipo object pueden usarse con todos los tipos que se derivan de object, como, por ejemplo, los tipos de referencia y los tipos de valor.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.

Hay varios tipos de variables en C#, entre otras, campos, elementos de matriz, variables locales y parámetros.There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. Las variables representan ubicaciones de almacenamiento.Variables represent storage locations. Cada variable tiene un tipo que determina qué valores se pueden almacenar en ella, como se muestra a continuación.Every variable has a type that determines what values can be stored in the variable, as shown below.

  • Tipo de valor distinto a NULLNon-nullable value type
    • Un valor de ese tipo exactoA value of that exact type
  • Tipos de valor NULLNullable value type
    • Un valor null o un valor de ese tipo exactoA null value or a value of that exact type
  • objetoobject
    • Una referencia null, una referencia a un objeto de cualquier tipo de referencia o una referencia a un valor de conversión boxing de cualquier tipo de valorA null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
  • Tipo de claseClass type
    • Una referencia null, una referencia a una instancia de ese tipo de clase o una referencia a una instancia de una clase derivada de ese tipo de claseA 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
  • Tipo de interfazInterface type
    • Un referencia null, una referencia a una instancia de un tipo de clase que implementa dicho tipo de interfaz o una referencia a un valor de conversión boxing de un tipo de valor que implementa dicho tipo de interfazA 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
  • Tipo de matrizArray type
    • Una referencia null, una referencia a una instancia de ese tipo de matriz o una referencia a una instancia de un tipo de matriz compatibleA null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
  • Tipo delegadoDelegate type
    • Una referencia null o una referencia a una instancia de un tipo delegado compatibleA null reference or a reference to an instance of a compatible delegate type

Estructura del programaProgram structure

Los conceptos organizativos clave de C# son *programas _, espacios de nombres, tipos, miembros y ensamblados .The key organizational concepts in C# are *programs _, namespaces, types, members, and assemblies. Los programas declaran tipos, que contienen miembros y pueden organizarse en espacios de nombres.Programs declare types, which contain members and can be organized into namespaces. Las clases, estructuras e interfaces son ejemplos de tipos.Classes, structs, and interfaces are examples of types. Los campos, los métodos, las propiedades y los eventos son ejemplos de miembros.Fields, methods, properties, and events are examples of members. Cuando se compilan programas de C#, se empaquetan físicamente en ensamblados.When C# programs are compiled, they're physically packaged into assemblies. Normalmente, los ensamblados tienen la extensión de archivo .exe o .dll, en función de si implementan aplicaciones o bibliotecas, respectivamente.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries, respectively.

Como ejemplo pequeño, considere la posibilidad de usar un ensamblado que contenga el código siguiente:As a small example, consider an assembly that contains the following code:

using System;

namespace Acme.Collections
{
    public class Stack<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;
            }
        }
    }
}

El nombre completo de esta clase es Acme.Collections.Stack.The fully qualified name of this class is Acme.Collections.Stack. La clase contiene varios miembros: un campo denominado top, dos métodos denominados Push y Pop, y una clase anidada denominada Entry.The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. La clase Entry contiene además tres miembros: un campo denominado next, un campo denominado data y un constructor.The Entry class further contains three members: a field named next, a field named data, and a constructor. Stack es una clase _genérica*.The Stack is a _generic* class. Tiene un parámetro de tipo, T, que se reemplaza con un tipo concreto cuando se usa.It has one type parameter, T that is replaced with a concrete type when it's used.

Nota

Una pila es una colección de tipo "el primero que entra es el último que sale" (FILO).A stack is a "first in - last out" (FILO) collection. Los elementos nuevos se agregan a la parte superior de la pila.New elements are added to the top of the stack. Cuando se quita un elemento, se quita de la parte superior de la pila.When an element is removed, it is removed from the top of the stack.

Los ensamblados contienen código ejecutable en forma de instrucciones de lenguaje intermedio (IL) e información simbólica en forma de metadatos.Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Antes de ejecutarlo, el compilador Just-In-Time (JIT) del entorno de ejecución de .NET convierte el código de IL de un ensamblado en código específico del procesador.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.

Como un ensamblado es una unidad autodescriptiva de funcionalidad que contiene código y metadatos, no hay necesidad de directivas #include ni archivos de encabezado de C#.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#. Los tipos y miembros públicos contenidos en un ensamblado determinado estarán disponibles en un programa de C# simplemente haciendo referencia a dicho ensamblado al compilar el programa.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. Por ejemplo, este programa usa la clase Acme.Collections.Stack desde el ensamblado acme.dll:For example, this program uses the Acme.Collections.Stack class from the acme.dll assembly:

using System;
using Acme.Collections;

class Example
{
    public static void Main()
    {
        var s = new 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()); // stack contains 1, 10
        Console.WriteLine(s.Pop()); // stack contains 1
        Console.WriteLine(s.Pop()); // stack is empty
    }
}

Para compilar este programa, necesitaría hacer referencia al ensamblado que contiene la clase de pila que se define en el ejemplo anterior.To compile this program, you would need to reference the assembly containing the stack class defined in the earlier example.

Los programas de C# se pueden almacenar en varios archivos de origen.C# programs can be stored in several source files. Cuando se compila un programa de C#, todos los archivos de origen se procesan juntos y se pueden hacer referencia entre sí de manera libre.When a C# program is compiled, all of the source files are processed together, and the source files can freely reference each other. Conceptualmente, es como si todos los archivos de origen estuviesen concatenados en un archivo de gran tamaño antes de que se procesen.Conceptually, it's as if all the source files were concatenated into one large file before being processed. En C# nunca se necesitan declaraciones adelantadas porque, excepto en contadas ocasiones, el orden de declaración es insignificante.Forward declarations are never needed in C# because, with few exceptions, declaration order is insignificant. C# no limita un archivo de origen a declarar solamente un tipo público ni precisa que el nombre del archivo de origen coincida con un tipo declarado en el archivo de origen.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.

En otros artículos de este paseo se explican estos bloques organizativos.Further articles in this tour explain these organizational blocks.