Paseo por .NETTour of .NET

.NET es una plataforma de desarrollo de uso general..NET is a general purpose development platform. Tiene varias características clave, como la compatibilidad con varios lenguajes de programación, modelos de programación asincrónica y simultánea e interoperabilidad nativa, que permiten una amplia variedad de escenarios en diversas plataformas.It has several key features, such as support for multiple programming languages, asynchronous and concurrent programming models, and native interoperability, which enable a wide range of scenarios across multiple platforms.

En este artículo, se ofrece un paseo guiado por algunas de las características clave de .NET.This article offers a guided tour through some of the key features of the .NET. Consulte el tema Componentes de la arquitectura .NET para obtener más información sobre las piezas de arquitectura de .NET y para qué se usan.See the .NET Architectural Components topic to learn about the architectural pieces of .NET and what they're used for.

Ejecución de ejemplos de códigoHow to run the code samples

Para obtener más información sobre cómo configurar un entorno de desarrollo para ejecutar los ejemplos de código, consulte el tema Introducción.To learn how to set up a development environment to run the code samples, see the Getting Started topic. Copie y pegue los ejemplos de código de esta página en su entorno para ejecutarlos.Copy and paste code samples from this page into your environment to execute them.

Lenguajes de programaciónProgramming languages

.NET admite varios lenguajes de programación..NET supports multiple programming languages. Las implementaciones de .NET implementan Common Language Infrastructure (CLI), que, entre otras cosas, especifica un entorno de ejecución independiente del lenguaje y la interoperabilidad del lenguaje.The .NET implementations implement the Common Language Infrastructure (CLI), which among other things specifies a language-independent runtime and language interoperability. Esto significa que elige cualquier lenguaje .NET para crear aplicaciones y servicios en .NET.This means that you choose any .NET language to build apps and services on .NET.

Microsoft desarrolla activamente y admite tres lenguajes .NET: C#, F# y Visual Basic (VB).Microsoft actively develops and supports three .NET languages: C#, F#, and Visual Basic (VB).

  • C# es simple, eficaz, incluye seguridad de tipos y está orientado a objetos, al mismo tiempo que mantiene la expresividad y elegancia de los lenguajes de estilo C.C# is simple, powerful, type-safe, and object-oriented, while retaining the expressiveness and elegance of C-style languages. Cualquiera que esté familiarizado con C y lenguajes similares, encuentra pocos problemas para adaptarse a C#.Anyone familiar with C and similar languages finds few problems in adapting to C#. Consulte la Guía de C# para más información sobre C#.Check out the C# Guide to learn more about C#.

  • F # es un lenguaje de programación multiplataforma, principalmente funcional, que también admite la programación tradicional imperativa y orientada en objetos.F# is a cross-platform, functional-first programming language that also supports traditional object-oriented and imperative programming. Consulte la Guía de F # para más información sobre F #.Check out the F# Guide to learn more about F#.

  • Visual Basic es un lenguaje fácil de aprender que se usa para crear una gran variedad de aplicaciones que se ejecutan en .NET.Visual Basic is an easy language to learn that you use to build a variety of apps that run on .NET. Entre los lenguajes .NET, la sintaxis de VB es la más cercana al idioma normal, lo que a menudo facilita el trabajo a las personas sin experiencia en desarrollo de software.Among the .NET languages, the syntax of VB is the closest to ordinary human language, often making it easier for people new to software development.

Administración de memoria automáticaAutomatic memory management

.NET usa la recolección de elementos no utilizados para proporcionar administración automática de memoria para los programas..NET uses garbage collection (GC) to provide automatic memory management for programs. La GC funciona con un enfoque diferido para la administración de memoria y prefiere el rendimiento de la aplicación sobre la recolección inmediata de la memoria.The GC operates on a lazy approach to memory management, preferring app throughput to the immediate collection of memory. Para más información sobre GC de .NET, consulte Fundamentals of garbage collection (GC) (Fundamentos de la recolección de elementos no utilizados [GC]).To learn more about the .NET GC, check out Fundamentals of garbage collection (GC).

Las dos líneas siguientes asignan memoria:The following two lines both allocate memory:

var title = ".NET Primer";
var list = new List<string>();

No hay ninguna palabra clave análoga para anular la asignación de memoria, ya que la anulación de la asignación se realiza automáticamente cuando el recolector de elementos no utilizados reclama la memoria a través de su ejecución programada.There's no analogous keyword to de-allocate memory, as de-allocation happens automatically when the garbage collector reclaims the memory through its scheduled run.

El recolector de elementos no utilizados es uno de los servicios que ayudan a garantizar la protección de la memoria.The garbage collector is one of the services that help ensure memory safety. Un programa tiene protección de la memoria si tiene acceso solo a la memoria asignada.A program is memory safe if it accesses only allocated memory. Por ejemplo, el entorno de ejecución garantiza que una aplicación no accede a memoria sin asignar más allá de los límites de una matriz.For instance, the runtime ensures that an app doesn't access unallocated memory beyond the bounds of an array.

En el ejemplo siguiente, el entorno de ejecución devuelve una excepción InvalidIndexException para activar la protección de la memoria:In the following example, the runtime throws an InvalidIndexException exception to enforce memory safety:

int[] numbers = new int[42];
int number = numbers[42]; // Will throw an exception (indexes are 0-based)

Trabajar con recursos no administradosWorking with unmanaged resources

Algunos objetos hacen referencia a recursos no administrados.Some objects reference unmanaged resources. Los recursos no administrados son recursos que el entorno de ejecución .NET no mantiene de forma automática.Unmanaged resources are resources that aren't automatically maintained by the .NET runtime. Por ejemplo, un identificador de archivo es un recurso no administrado.For example, a file handle is an unmanaged resource. Un objeto FileStream es un objeto administrado, pero hace referencia a un identificador de archivo, que es uno no administrado.A FileStream object is a managed object, but it references a file handle, which is unmanaged. Cuando haya acabado de usar FileStream, deberá liberar el identificador de archivo.When you're done using the FileStream, you need to release the file handle.

En .NET, los objetos que hacen referencia a recursos no administrados implementan la interfaz de IDisposable.In .NET, objects that reference unmanaged resources implement the IDisposable interface. Cuando haya acabado de usar el objeto, deberá llamar al método Dispose() del objeto, que es el responsable de liberar cualquier recurso no administrado.When you're done using the object, you call the object's Dispose() method, which is responsible for releasing any unmanaged resources. Los lenguajes .NET ofrecen una sintaxis using muy útil para esos objetos, como se muestra en el ejemplo siguiente:.NET languages provide a convenient using syntax for such objects, as shown in the following example:

using System.IO;

using (FileStream stream = GetFileStream(context))
{
    // Operations on the stream
}

Cuando el bloque using se completa, el entorno de ejecución .NET llama automáticamente al método Dispose() del objeto stream, que libera el identificador de archivo.Once the using block completes, the .NET runtime automatically calls the stream object's Dispose() method, which releases the file handle. El entorno de ejecución también sigue el mismo procedimiento en caso de que una excepción provoque que el control abandone el bloque.The runtime also does this if an exception causes control to leave the block.

Para obtener más información, consulte los siguientes temas:For more details, see the following topics:

Seguridad de tiposType safety

Un objeto es una instancia de un tipo específico.An object is an instance of a specific type. Las únicas operaciones permitidas para un objeto determinado son las de su tipo.The only operations allowed for a given object are those of its type. Un tipo Dog puede tener métodos Jump y WagTail, pero no un método SumTotal.A Dog type may have Jump and WagTail methods but not a SumTotal method. Un programa solo llama a los métodos que pertenecen a un tipo determinado.A program only calls the methods belonging to a given type. Todas las demás llamadas producirán un error en tiempo de compilación o una excepción en tiempo de ejecución (en el caso de usar características dinámicas o object).All other calls result in either a compile-time error or a run-time exception (in case of using dynamic features or object).

Los lenguajes .NET están orientados a objetos, con las jerarquías de clases base y derivadas..NET languages are object-oriented with hierarchies of base and derived classes. El entorno de ejecución .NET solo permite llamadas y conversiones de objetos que se alineen con la jerarquía de objetos.The .NET runtime only allows object casts and calls that align with the object hierarchy. Recuerde que cada tipo definido en cualquier lenguaje .NET se deriva del tipo Object base.Remember that every type defined in any .NET language derives from the base Object type.

Dog dog = AnimalShelter.AdoptDog(); // Returns a Dog type.
Pet pet = (Pet)dog; // Dog derives from Pet.
pet.ActCute();
Car car = (Car)dog; // Will throw - no relationship between Car and Dog.
object temp = (object)dog; // Legal - a Dog is an object.

La seguridad de tipos también se usa para ayudar a aplicar la encapsulación a través de la garantía de la fidelidad de las palabras clave del descriptor de acceso.Type safety is also used to help enforce encapsulation by guaranteeing the fidelity of the accessor keywords. Las palabras clave del descriptor de acceso son artefactos que controlan el acceso a los miembros de un tipo determinado a través de otro código.Accessor keywords are artifacts which control access to members of a given type by other code. Normalmente se usan para distintos tipos de datos dentro de un tipo, que se usan para administrar su comportamiento.These are usually used for various kinds of data within a type that are used to manage its behavior.

private Dog _nextDogToBeAdopted = AnimalShelter.AdoptDog()

C#, VB y F# admiten la inferencia de tipo de variable local.C#, VB, and F# support local type inference. La inferencia de tipos significa que el compilador deduce el tipo de la expresión en el lado izquierdo a partir de la expresión en el lado derecho.Type inference means that the compiler deduces the type of the expression on the left-hand side from the expression on the right-hand side. Esto no significa que la seguridad de tipos se divida o evite.This doesn't mean that the type safety is broken or avoided. El tipo resultante tiene un tipo seguro con todo lo que ello implica.The resulting type does have a strong type with everything that implies. En el ejemplo anterior, se vuelve a escribir dog para introducir la inferencia de tipos, y el resto del ejemplo no se modifica:From the previous example, dog is rewritten to introduce type inference, and the remainder of the example is unchanged:

var dog = AnimalShelter.AdoptDog();
var pet = (Pet)dog;
pet.ActCute();
Car car = (Car)dog; // will throw - no relationship between Car and Dog
object temp = (object)dog; // legal - a Dog is an object
car = (Car)temp; // will throw - the runtime isn't fooled
car.Accelerate() // the dog won't like this, nor will the program get this far

F# tiene incluso más funcionalidades de inferencia de tipos que la inferencia de tipo de variable local o método encontrada en C# y VB.F# has even further type inference capabilities than the method-local type inference found in C# and VB. Para obtener más información, consulte Type Inference (Inferencia de tipos).To learn more, see Type Inference.

Delegados y expresiones lambdaDelegates and lambdas

Un delegado se representa mediante una firma de método.A delegate is represented by a method signature. Cualquier método con esa firma puede asignarse al delegado y se ejecuta cuando se invoca el delegado.Any method with that signature can be assigned to the delegate and is executed when the delegate is invoked.

Los delegados son como los punteros de función de C++, pero tienen seguridad de tipos.Delegates are like C++ function pointers except that they're type safe. Son un tipo de método sin conexión en el sistema de tipos de CLR.They're a kind of disconnected method within the CLR type system. Los métodos regulares están conectados a una clase y solo se pueden llamar a través de convenciones de llamadas estáticas o de instancias.Regular methods are attached to a class and are only directly callable through static or instance calling conventions.

En .NET, los delegados se usan habitualmente en controladores de eventos, en la definición de operaciones asincrónicas y en las expresiones lambda, que son los pilares de LINQ.In .NET, delegates are commonly used in event handlers, in defining asynchronous operations, and in lambda expressions, which are a cornerstone of LINQ. Obtenga más información en el tema Delegados y expresiones lambda.Learn more in the Delegates and lambdas topic.

GenéricosGenerics

Los genéricos permiten al programador introducir un parámetro de tipo al diseñar sus clases, que permite al código de cliente (los usuarios del tipo) especificar el tipo exacto que se debe usar en lugar del parámetro de tipo.Generics allow the programmer to introduce a type parameter when designing their classes that allows the client code (the users of the type) to specify the exact type to use in place of the type parameter.

Los genéricos se agregaron para ayudar a los programadores a implementar estructuras de datos genéricos.Generics were added to help programmers implement generic data structures. Antes de que se agregasen, para que un tipo como List fuera genérico, tendría que trabajar con elementos que fueran de tipo object.Before their arrival in order for a type such as the List type to be generic, it would have to work with elements that were of type object. Esto tenía varios problemas de rendimiento y semántica, junto con los posibles errores sutiles en tiempo de ejecución.This had various performance and semantic problems, along with possible subtle runtime errors. Lo más destacado de esto último se produciría cuando una estructura de datos contiene, por ejemplo, enteros y cadenas, y se inicia la excepción InvalidCastException al trabajar con los miembros de la lista.The most notorious of the latter is when a data structure contains, for instance, both integers and strings, and an InvalidCastException is thrown on working with the list's members.

En el siguiente ejemplo, se muestra una ejecución básica de programa mediante una instancia de tipos List<T>:The following sample shows a basic program running using an instance of List<T> types:

using System;
using System.Collections.Generic;

namespace GenericsSampleShort
{
    public static void Main(string[] args)
    {
        // List<string> is the client way of specifying the actual type for the type parameter T
        List<string> listOfStrings = new List<string> { "First", "Second", "Third" };

        // listOfStrings can accept only strings, both on read and write.
        listOfStrings.Add("Fourth");

        // Below will throw a compile-time error, since the type parameter
        // specifies this list as containing only strings.
        listOfStrings.Add(1);
    }
}

Para obtener más información, consulte el tema Información general (genéricos) de tipos genéricos.For more information, see the Generic types (Generics) overview topic.

Programación asincrónicaAsync programming

La programación asincrónica es un concepto de primera clase en .NET, con compatibilidad asincrónica en el entorno de ejecución, las bibliotecas del marco y las construcciones de lenguaje .NET.Async programming is a first-class concept within .NET with async support in the runtime, framework libraries, and .NET language constructs. Internamente, se basa en objetos (como Task) que sacan partido del sistema operativo para realizar trabajos dependientes de E/S de la forma más eficaz posible.Internally, they're based on objects (such as Task), which take advantage of the operating system to perform I/O-bound jobs as efficiently as possible.

Para obtener más información sobre la programación asincrónica en .NET, comience con el tema Async en profundidad.To learn more about async programming in .NET, start with the Async overview topic.

Language-Integrated Query (LINQ)Language Integrated Query (LINQ)

LINQ es un conjunto eficaz de características para C# y VB que permiten escribir código simple y declarativo para operar en los datos.LINQ is a powerful set of features for C# and VB that allow you to write simple, declarative code for operating on data. Los datos pueden estar en muchos formatos (como objetos en memoria, una base de datos SQL o un documento XML), pero el código LINQ que escriba normalmente no es diferente según el origen de datos.The data can be in many forms (such as in-memory objects, a SQL database, or an XML document), but the LINQ code you write typically doesn't differ by data source.

Para obtener más información y ver algunos ejemplos, consulte el tema LINQ (Language Integrated Query).To learn more and see some samples, see the LINQ (Language Integrated Query) topic.

Interoperabilidad nativaNative interoperability

Cada sistema operativo incluye una interfaz de programación de aplicaciones (API) que proporciona servicios del sistema.Every operating system includes an application programming interface (API) that provides system services. .NET proporciona varias maneras de llamar a esas API..NET provides several ways to call those APIs.

La manera principal de crear interoperabilidad nativa es a través de la "invocación de plataforma" o P/Invoke para abreviar, que se admite en las plataformas Linux y Windows.The main way to do native interoperability is via "platform invoke" or P/Invoke for short, which is supported across Linux and Windows platforms. Una manera de crear interoperabilidad nativa exclusiva de Windows se conoce como "Interoperabilidad COM", que se usa para trabajar con componentes COM en código administrado.A Windows-only way of doing native interoperability is known as "COM interop," which is used to work with COM components in managed code. Se basa en la infraestructura de P/Invoke, pero funciona de forma ligeramente diferente.It's built on top of the P/Invoke infrastructure, but it works in subtly different ways.

La mayoría de la compatibilidad de interoperabilidad de Mono (y, por tanto, de Xamarin) para Java y Objective-C se compila de forma similar, es decir, usan los mismos principios.Most of Mono's (and thus Xamarin's) interoperability support for Java and Objective-C are built similarly, that is, they use the same principles.

Obtenga más información sobre la interoperabilidad nativa en el tema Interoperabilidad nativa.Read more about it native interoperability in the Native interoperability topic.

Código no seguroUnsafe code

Según la compatibilidad con el lenguaje, CLR le permite tener acceso a memoria nativa y usar la aritmética de punteros a través de código unsafe.Depending on language support, the CLR lets you access native memory and do pointer arithmetic via unsafe code. Estas operaciones son necesarias para determinados algoritmos y para la interoperabilidad del sistema.These operations are needed for certain algorithms and system interoperability. Aunque es eficaz, se desaconseja el uso de código no seguro a menos que sea necesario para la interoperabilidad con las API del sistema o para implementar el algoritmo más eficaz.Although powerful, use of unsafe code is discouraged unless it's necessary to interop with system APIs or implement the most efficient algorithm. Es posible que el código no seguro no se ejecute del mismo modo en entornos diferentes y que también pierda las ventajas de un recolector de elementos no utilizados y de la seguridad de tipos.Unsafe code may not execute the same way in different environments and also loses the benefits of a garbage collector and type safety. Se recomienda limitar y centralizar el código no seguro lo máximo posible, y probar el código a conciencia.It's recommended to confine and centralize unsafe code as much as possible and test that code thoroughly.

El ejemplo siguiente es una versión modificada del método ToString() desde la clase StringBuilder.The following example is a modified version of the ToString() method from the StringBuilder class. Ilustra cómo mediante el código unsafe se puede implementar de forma eficiente un algoritmo desplazándose por los fragmentos de memoria directamente:It illustrates how using unsafe code can efficiently implement an algorithm by moving around chunks of memory directly:

public override String ToString()
{
    if (Length == 0)
        return String.Empty;

    string ret = string.FastAllocateString(Length);
    StringBuilder chunk = this;
    unsafe
    {
        fixed (char* destinationPtr = ret)
        {
            do
            {
                if (chunk.m_ChunkLength > 0)
                {
                    // Copy these into local variables so that they are stable even in the presence of ----s (hackers might do this)
                    char[] sourceArray = chunk.m_ChunkChars;
                    int chunkOffset = chunk.m_ChunkOffset;
                    int chunkLength = chunk.m_ChunkLength;

                    // Check that we will not overrun our boundaries.
                    if ((uint)(chunkLength + chunkOffset) <= ret.Length && (uint)chunkLength <= (uint)sourceArray.Length)
                    {
                        fixed (char* sourcePtr = sourceArray)
                            string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
                    }
                }
                chunk = chunk.m_ChunkPrevious;
            } while (chunk != null);
        }
    }
    return ret;
}

Pasos siguientesNext steps

Si está interesado en un paseo por las características de C#, consulte Paseo por C#.If you're interested in a tour of C# features, check out Tour of C#.

Si está interesado en un paseo por las características de F#, consulte Tour of F# (Paseo por F#).If you're interested in a tour of F# features, see Tour of F#.

Si quiere empezar a escribir su propio código, consulte Introducción.If you want to get started with writing code of your own, visit Getting Started.

Para más información sobre los principales componentes de. NET, consulte Componentes de la arquitectura .NET.To learn about important components of .NET, check out .NET Architectural Components.