Saltar al contenido

La plataforma .NET

La plataforma de Microsoft de arriba abajo: el estándar y su motor de ejecución, los ensamblados y el código intermedio, las versiones que hay que distinguir, los dos lenguajes principales con sus elementos y estructuras, el acceso a datos y el desarrollo web con ASP.NET.

CLI, CLR y el código intermedio

La plataforma .NET está descrita por un estándar, no por un producto, y de ese estándar salen todas las siglas del tema. Conviene fijarlas de una en una porque se preguntan casi siempre en forma de definición suelta.

SiglaNombreQué es
CLICommon Language InfrastructureEl estándar completo de la plataforma: formato de los ejecutables, sistema de tipos y entorno de ejecución
VESVirtual Execution SystemEl entorno de ejecución que describe el estándar. Es la especificación, no el programa
CLRCommon Language RuntimeLa implementación real de ese entorno, es decir, el motor que ejecuta. Es el equivalente de la máquina virtual de Java
CILCommon Intermediate LanguageEl código intermedio al que compilan todos los lenguajes de la plataforma. Antes se llamaba MSIL. Es el equivalente del bytecode
CTSCommon Type SystemEl sistema de tipos común: clases, tipos por valor, interfaces y delegados, definidos una vez para todos los lenguajes
CLSCommon Language SpecificationEl subconjunto de reglas que un lenguaje debe cumplir para poder convivir con los demás en la plataforma

El motor de ejecución hace mucho más que interpretar instrucciones: carga en memoria los tipos que van haciendo falta, compila el código intermedio a código nativo, gestiona los hilos, propaga las excepciones, libera la memoria con su recolector de basura y aplica las comprobaciones de seguridad. Es exactamente el mismo reparto de tareas que en el lado de Java, con otros nombres.

Queda una sigla más, el GAC (Global Assembly Cache), un almacén común de la máquina donde se registran bibliotecas compartidas por varias aplicaciones, con una función parecida a la del classpath. Importa un matiz: el GAC pertenece a .NET Framework, el .NET moderno no lo usa y cada aplicación lleva consigo sus propias dependencias.

CTS y CLS se confunden sin remedio si no se separan así: el CTS dice qué tipos existen, el CLS dice qué parte de esos tipos puede usar un lenguaje para que otro lenguaje lo entienda. Uno describe, el otro restringe.

Para el examen

  • CLI: el estándar

  • CLR: el motor de ejecución; equivale a la JVM

  • CIL: el código intermedio, antes MSIL; equivale al bytecode

  • CTS y CLS: el sistema de tipos común y las reglas mínimas para que los lenguajes convivan

Ensamblados, compilación y las versiones de .NET

AMPLIADO (el enunciado oficial exige la plataforma completa, y este apartado del documento de origen no llevaba marca). Un ensamblado es la unidad de despliegue y de versión de .NET: el fichero .dll o .exe que se genera al compilar. Dentro no hay código nativo, sino código intermedio acompañado de metadatos que describen los tipos que contiene, de un manifiesto con su nombre, su versión y sus dependencias, y de los recursos que necesite.

La compilación ocurre en dos tiempos, igual que en Java. Primero el compilador de cada lenguaje traduce el fuente a código intermedio y produce el ensamblado. Después, en ejecución, el compilador justo a tiempo (JIT) traduce ese código intermedio al código nativo de la máquina concreta donde se está ejecutando. De ahí sale la propiedad más citada de la plataforma: como el paso de C#, de VB.NET o de F# a código intermedio ya está hecho, todos los lenguajes acaban siendo el mismo por debajo y pueden usarse entre sí sin ninguna pasarela.

AMPLIADO. Las versiones de .NET son un lío histórico que se pregunta con frecuencia, y se aclara en tres pasos.

ProductoCuándoQué lo caracteriza
.NET FrameworkDesde 2002El original. Solo Windows, ligado al sistema operativo. Sigue mantenido, pero ya no recibe funcionalidad nueva
.NET CoreDesde 2016Reescritura multiplataforma, de código abierto, modular y con despliegue independiente del sistema
.NET (a secas)Desde 2020La convergencia de los dos anteriores en un único producto, numerado 5, 6, 7 y siguientes

Dos consecuencias prácticas. La primera: una aplicación nueva se escribe sobre el .NET moderno, y .NET Framework solo aparece en el mantenimiento de aplicaciones antiguas atadas a Windows. La segunda: la numeración del producto y la del motor de ejecución no van del brazo, así que citar «la versión de .NET» no dice por sí solo qué motor hay debajo.

.NET Core no es una versión reducida de .NET Framework, ni .NET 5 la continuación de .NET Framework 4.8. Son dos líneas distintas que confluyeron en 2020 en un único producto multiplataforma y de código abierto.

Para el examen

  • Ensamblado: la unidad de despliegue: .dll o .exe

  • Qué contiene: código intermedio más metadatos y manifiesto

  • .NET Framework: 2002, solo Windows

  • .NET Core: 2016, multiplataforma

  • .NET a secas: desde 2020, unifica los dos

C# y VB.NET, y los tipos que declaran

AMPLIADO en su primera mitad. La plataforma admite varios lenguajes, y dos concentran casi todo su uso. C# es el principal: su sintaxis viene de la familia de C, C++ y Java, delimita los bloques con llaves, termina las sentencias con punto y coma y distingue mayúsculas de minúsculas. VB.NET continúa la tradición de Visual Basic: delimita los bloques con palabras («If» y «End If», «Sub» y «End Sub»), no usa punto y coma y no distingue mayúsculas de minúsculas. Los dos compilan al mismo código intermedio y tienen la misma potencia; la diferencia es de sintaxis y de uso real, ampliamente a favor de C#.

Sobre esa base, los tipos que se pueden declarar son cuatro, y distinguirlos es lo que de verdad se pregunta.

TipoQué esHerencia
ClaseLa plantilla habitual, con campos y métodos, de la que se crean objetos. Se maneja por referenciaHereda de otra clase e implementa interfaces
EstructuraUn agrupador de datos, parecido a la clase, pero que se maneja por valor. También admite métodosNo hereda, aunque sí puede implementar interfaces
MóduloUn contenedor de utilidades cuyos miembros son todos compartidos. Existe una única copia durante toda la vida del programa y no hay que crearlaNi hereda ni implementa interfaces
InterfazUn contrato de operaciones sin cuerpo, que las clases se comprometen a cumplirPuede heredar de otras interfaces

Una clase se puede además marcar como parcial, lo que permite repartir su declaración entre varios ficheros y que el compilador los reúna. Es lo que hace posible que una herramienta genere automáticamente una mitad del código mientras la otra mitad la escribe una persona, sin que se pisen.

El otro elemento característico es la propiedad. Una propiedad se usa desde fuera como si fuera un campo, con una simple asignación o lectura, pero por dentro ejecuta un bloque de lectura y otro de escritura. No rompe la encapsulación: la conserva y además la disimula, porque permite validar, convertir o registrar sin que quien la usa tenga que llamar a un método. Si solo se declara uno de los dos bloques, la propiedad queda de solo lectura o de solo escritura.

csharp
public class Alumno
{
    private string _modalidad;

    // se usa como un campo, pero controla lo que entra
    public string Modalidad
    {
        get { return _modalidad; }
        set
        {
            if (value != "largo" && value != "mediano" && value != "express")
                throw new ArgumentException("Modalidad no válida");
            _modalidad = value;
        }
    }
}

var alumno = new Alumno();
alumno.Modalidad = "express";   // por dentro pasa por el bloque set

Para el examen

  • Clase: tipo por referencia

  • Estructura: tipo por valor; no hereda

  • Módulo e interfaz: miembros compartidos y contrato

  • Propiedad: se usa como un campo, pero ejecuta sus bloques de lectura y escritura

Herencia, interfaces y modificadores

Los mecanismos de la orientación a objetos son los mismos que en Java, pero las palabras cambian, y ahí está el trabajo. En VB.NET, Inherits expresa la herencia, tanto entre clases como entre interfaces, e Implements expresa que una clase cumple una interfaz. Dentro de un objeto, Me es la referencia a la instancia actual y MyBase la referencia a la clase de la que se hereda.

IdeaEn VB.NETEn C#Equivalente en Java
La instancia actualMethisthis
La clase padreMyBasebasesuper
Clase que hay que heredar obligatoriamenteMustInheritabstractabstract
Clase de la que nadie puede heredarNotInheritablesealedfinal
Método que se puede sobrescribirOverridablevirtualCualquier método, salvo que sea final
Método que hay que sobrescribirMustOverrideabstractabstract
Método que no se puede sobrescribirNotOverridablesealedfinal
Miembro que pertenece al tipo y no al objetoSharedstaticstatic

Hay una diferencia de fondo con Java que conviene subrayar. En Java cualquier método se puede sobrescribir salvo que se declare final; en .NET ocurre al revés: un método solo se puede sobrescribir si su autor lo ha permitido expresamente, y quien lo sobrescribe está obligado a decirlo con la palabra reservada correspondiente. La plataforma prefiere que las dos partes lo declaren en voz alta.

Además de clases, estructuras, interfaces y enumeraciones, .NET tiene un tipo pensado para transportar datos, el registro (record), que se comporta como una fila de una tabla, y un mecanismo de eventos: un miembro que se declara como evento, se dispara desde el código y al que otras partes del programa se suscriben para reaccionar cuando ocurra.

Para el examen

  • Me y MyBase: this y super

  • MustInherit y NotInheritable: abstract y sealed o final

  • Shared: static

  • Sobrescritura: en .NET solo si se declaró virtual u Overridable; en Java, salvo que sea final

Estructuras de control

Las estructuras de control son las de cualquier lenguaje imperativo, y lo único que cambia respecto a Java es la forma de escribirlas. En VB.NET el bloque no se abre con una llave, sino que se cierra con una palabra: a If le corresponde End If, a Sub le corresponde End Sub y así con todas.

Para quéEn VB.NETEn Java
DecidirIf ... Then / ElseIf / Else / End Ifif / else if / else
Decidir entre varios valoresSelect Case / Case / Case Else / End Selectswitch / case / default
Repetir comprobando antesWhile ... End Whilewhile
Repetir comprobando al finalDo ... Loop Until, o Do While ... Loopdo-while
Repetir un número de vecesFor ... To ... Nextfor
Recorrer una colecciónFor Each ... In ... Nextfor-each
Salir de un bucleExit Forbreak
Controlar erroresTry / Catch / Finally / End Trytry / catch / finally
vbnet
' cuántos temas quedan por repasar
If pendientes = 0 Then
    mensaje = "No queda nada por repasar."
ElseIf pendientes = 1 Then
    mensaje = "Queda 1 tema por repasar."
Else
    mensaje = $"Quedan {pendientes} temas por repasar."
End If

' recorrer la lista de subtemas fallados
For Each subtema As String In fallados
    programarRepaso(subtema)
Next

Los métodos también se parten en dos según devuelvan o no un valor: los que no devuelven nada se declaran como procedimiento y los que sí, como función. En Java esa distinción no existe como tal, porque todo son métodos y lo que cambia es que el tipo de retorno sea void o no.

Para el examen

  • Cierre de bloques en VB.NET: con palabras: End If, End Sub

  • Select Case: equivale al switch

  • Sub frente a Function: el procedimiento no devuelve; la función sí

Acceso a datos: ADO.NET, Entity Framework y LINQ

El acceso a datos de .NET repite la misma pareja de niveles que el lado de Java, y esa correspondencia es lo que hace fácil el apartado.

PiezaQué esSu equivalente en Java
ADO.NETLa API de bajo nivel: conexión, comando, parámetros y lectura del resultado, con SQL escrito a manoJDBC
Entity FrameworkEl ORM de la plataforma: la correspondencia entre clases y tablas, con el SQL generado por la bibliotecaJPA con Hibernate
LINQUn lenguaje de consulta integrado en el propio lenguaje de programaciónJPQL, aunque LINQ va más allá

Entity Framework se incorporó a la plataforma a partir de la versión 3.5 y funciona igual que cualquier ORM: la aplicación trabaja con objetos, el ORM traduce a SQL y el programador deja de escribir sentencias. Existe además NHibernate, que es la traslación a .NET del Hibernate del mundo Java, y que se cita a menudo como su alternativa.

LINQ merece atención aparte porque no tiene equivalente exacto en Java. Es un lenguaje de consulta escrito dentro del propio lenguaje de programación, con lo que el compilador lo revisa como revisa cualquier otra instrucción. Y lo que consulta no tiene por qué ser una base de datos: la misma consulta sirve para una colección en memoria, para una base de datos relacional o para un documento XML, porque lo que cambia por debajo es el proveedor.

csharp
// la misma consulta valdría sobre una lista en memoria o sobre la base de datos
var flojos = from i in contexto.Intentos
             where i.PorcentajeAciertos < 50
             orderby i.Fecha descending
             select new { i.SlugSubtema, i.PorcentajeAciertos };

foreach (var intento in flojos)
    Console.WriteLine($"{intento.SlugSubtema}: {intento.PorcentajeAciertos}%");

Que la consulta esté dentro del lenguaje tiene una consecuencia que se pregunta: los errores de una consulta LINQ los detecta el compilador, mientras que un error en una cadena de SQL no aparece hasta que la sentencia se lanza contra la base de datos.

Para el examen

  • ADO.NET: el equivalente de JDBC

  • Entity Framework: el equivalente de JPA con Hibernate

  • LINQ: lenguaje de consulta integrado en el propio lenguaje

  • Su ventaja: los errores los caza el compilador

Aplicaciones y servicios web: ASP.NET, IIS y Kestrel

El motor de ejecución no sabe nada de páginas web: no entiende de peticiones ni de respuestas HTTP. Esa capa la aporta ASP.NET, y en su versión moderna, ASP.NET Core, reúne en un único marco de trabajo lo que antes eran dos: el desarrollo de páginas con modelo, vista y controlador, y el desarrollo de servicios REST.

  • ASP.NET MVC: modelo, vista y controlador. El flujo entra siempre por un controlador, que coordina la lógica del modelo y elige la vista que se devuelve. Cada controlador tiene una ruta asociada, igual que un servlet tiene su URL, y esas rutas se configuran en un punto único de la aplicación.
  • Razor: la tecnología con la que se escriben las vistas, mezclando marcado y código como si fueran plantillas.
  • ASP.NET Web API: la parte orientada a servicios REST, con peticiones y respuestas en JSON.
  • Servicios SOAP: el estilo clásico, basado en XML y descrito por un estándar del W3C. En la plataforma sus puntos de acceso se publicaban con la extensión .asmx, y para escenarios avanzados, como la seguridad a nivel de mensaje, se recurría a WCF.

Conviene fijar la correspondencia correcta con el mundo Java, porque es donde más se falla: los servicios SOAP se corresponden con JAX-WS, y los servicios REST de ASP.NET Web API se corresponden con JAX-RS. ASP.NET MVC, en cambio, no es el equivalente de JAX-RS: es un marco de páginas, más cercano a Jakarta Faces o a Jakarta MVC.

Falta el servidor. En Windows, el servidor de referencia es IIS (Internet Information Services), que hace tres papeles a la vez: sirve contenido estático como cualquier servidor web, ejecuta aplicaciones .NET y puede actuar también como servidor de transferencia de ficheros. Su configuración por aplicación vive en un fichero propio, el web.config. En el .NET moderno y multiplataforma el papel de servidor lo hace Kestrel, que va incorporado en ASP.NET Core y funciona igual en Windows y en Linux, normalmente con otro servidor delante haciendo de intermediario.

La correspondencia limpia es: JAX-WS con los servicios SOAP, JAX-RS con ASP.NET Web API, y el servidor de aplicaciones Jakarta EE con la pareja IIS más el motor de ASP.NET, o con Kestrel en el .NET moderno.

Para el examen

  • ASP.NET Core: reúne MVC y Web API

  • Vistas de MVC: Razor

  • Correspondencias: SOAP con JAX-WS, y ASP.NET Web API con JAX-RS

  • Servidores: IIS con su web.config, o Kestrel en el .NET moderno