Está en la página 1de 69

Microsoft .

NET
{Arquitectura y Fundamentos}

Sergio Andrs Vargas A. MCTSMCS- MCT-MCP OCP - OCA


Twitter Facebook Blog IM serandvaraco http://www.facebook.com/unespacioparanet http://unespacioparanet.appfuture.net serandvaraco@hotmail.com

@serandvaraco

Introduccin a Microsoft .NET


Qu no es .NET? Qu es .NET? .NET Como evolucin de COM

Qu NO es .NET?
.NET no es un Sistema Operativo
.NET no es un Lenguaje de Programacin .NET no es un Entorno de Desarrollo

.NET no es un Servidor de Aplicaciones


.NET no es un producto empaquetado que se pueda comprar como tal

Qu es .NET?
Plataforma de Desarrollo compuesta de Entorno de Ejecucin (Runtime) Bibliotecas de Funcionalidad (Class Library) Lenguajes de Programacin Compiladores Herramientas de Desarrollo (IDE & Tools) Guas de Arquitectura

La evolucin de la plataforma COM

Versin 4 con novedades Instalado por Windows 7

Instalado por Windows Vista, Windows Server 2008

Versin 3.5 SP1 con novedades

Versin 3.5 SP1 con novedades

Libreras Administradas CLR 1.1

Libreras Administradas

Libreras Administradas (adicin de WPF, WCF, WF)

Libreras Administradas

Libreras Administradas

CLR 2.0

CLR 2.0

CLR 2.0

CLR 4

.NET Framework 1.1 SP1

.NET Framework 2.0 SP2

.NET Framework 3.0 SP1

.NET Framework 3.5 SP1

.NET Framework 4

Preview MetroStyle

Caractersticas de .NET (1/2)

Plataforma de ejecucin intermedia 100% Orientada a Objetos Multilenguaje Plataforma Empresarial de Misin Crtica

Caractersticas de .NET (2/2)


Modelo de Programacin nico para todo tipo de aplicaciones y dispositivos de hardware Se integra fcilmente con aplicaciones existentes desarrolladas en plataformas Microsoft Se integra fcilmente con aplicaciones desarrolladas en otras plataformas

Plataforma de Ejecucin Intermedia

Aplicacin .NET
Microsoft .NET

Lenguajes de Programacin

Libreras de Funcionalidad
Entorno de Ejecucin

Entorno de Desarrollo

Sistema Operativo (Familia Windows)

Qu es el .NET Framework?
Paquete de software fundamental de la plataforma .NET. Incluye:
Entorno de Ejecucin (Runtime) Bibliotecas de Funcionalidad (Class Library)

Se distribuye en forma libre y gratuita Existen tres variantes principales:


.NET Framework Redistributable Package
.NET Framework SDK .NET Compact Framework

Est instalado por defecto en Windows 2003 Server o superior

Dnde instalar el .NET Framework?


Cliente
Aplicacin de Escritorio Aplicacin Web

Servidor

Aplicacin de Consola Aplicacin Mvil

.NET Compact Framework

* Slo si la aplicacin es distribuda

Arquitectura del .NET Framework


VB C++ C# J# Common Language Specification
.NET Framework SDK

ASP.NET
.NET Framework Redistributable

Windows Forms ADO.NET y XML

Class Library

.NET Framework

Base Class Library Common Language Runtime

Windows

COM+ Services

CLR - Arquitecturas de Ejecucin de Aplicaciones

CLR Common Language Runtime


El CLR es el motor de ejecucin (runtime) de .NET Caractersticas Compilacin Just-In-Time (JIT) Gestin automtica de memoria (Garbage Collector) Gestin de errores consistente (Excepciones) Ejecucin basada en componentes (Assemblies) Gestin de Seguridad Multithreading

CLR Componentes Internos

CLR Proceso de Compilacin

Cdigo Fuente

Compilador

Assembly (MSIL)

Cualquier lenguaje .NET

Biblioteca o Ejecutable

CLR - MSIL
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint maxstack 8 L_0000: ldstr "Hola Mundo" L_0005: call void [mscorlib]System.Console::WriteLine(string) L_000a: ret }

Qu es un Assembly?
Un Assembly es la unidad mnima de ejecucin, distribucin, instalacin y versionado de aplicaciones .NET
Descripcin de Tipos MiBiblioteca.DLL Metadata Recursos Cdigo Compilado MSIL
Clases Clases Base Interfaces Implementadas Atributos de las Clases Mtodos de las Clases

Manifiesto del Assembly


Nombre Versin Cultura
Otros Assemblies Permisos de Seguridad Tipos Externos

Assemblies - Aplicaciones .NET


Uno o ms Assemblies Al ejecutar una aplicacin, cmo ubico los assemblies necesarios?
El Class Loader busca en el directorio local (preferido) Global Assembly Cache (GAC)

Diferentes aplicaciones pueden usar diferentes versiones Actualizaciones ms simples Desinstalacin ms simple

.NET Framework Class Library


Conjunto de Tipos bsicos (clases, interfaces, etc.) que vienen includos en el .NET Framework Los tipos estn organizados en jerarquas lgicas de nombres, denominados NAMESPACES Los tipos son INDEPENDIENTES del lenguaje de desarrollo Es extensible y totalmente orientada a objetos

.NET Framework Class Library


El namespace raz es SYSTEM
System.Web
Services Description Discovery Protocols Caching Configuration Security SessionState UI HtmlControls WebControls

System.Windows.Forms
Design ComponentModel

System.Drawing
Drawing2D Imaging Printing Text

System.Data
OleDb Common Odbc SqlClient

System.Xml
XSLT XPath Serialization

System
Collections
Configuration Diagnostics Globalization

IO
Net Reflection Resources

Security
ServiceProcess Text Threading

Runtime InteropServices
Remoting Serialization

Common Language Specification (CLS)


Especificacin que estandariza una serie de caractersticas soportadas por el CLR Contrato entre diseadores de lenguajes de programacin y autores de bibliotecas Permite la interoperabilidad entre lenguajes Microsoft provee implementaciones de 4 lenguajes, todos compatibles con CLS Microsoft Visual Basic .NET Microsoft Visual C# .NET Microsoft Visual J#.NET Microsoft Visual C++.NET

Common Language Specification (CLS)


El resto de la industria y el sector acadmico han desarrollado ms de 20 lenguajes compatibles con la especificacin CLS

C++.NET Delphi Java

Visual Basic.NET
PHP Perl

C#
Python

J#
JavaScript

Pascal
Oberon Cobol

Haskell
Mondrian Fortran

LISP
Smalltalk APL

Prolog
Eiffel Objective Caml

RPG
ML Scheme Mercury

CLS - Eleccin del lenguaje


.NET posee un nico runtime (el CLR) y un nico conjunto de bibliotecas para todos los lenguajes No hay diferencias notorias de performance entre los lenguajes provistos por Microsoft El lenguaje a utilizar, en gral., depender de su experiencia previa con otros lenguajes o de gustos personales Si conoce Java, Delphi, C++, etc. C# Si conoce Visual Basic o VBScript VB.NET Los tipos de aplicaciones .NET son INDEPENDIENTES del lenguaje que elija

Modelo de Ejecucin del CLR


Cdigo Fuente
VB.NET Compilador VB.NET Assembly Cdigo MSIL C# Compilador C# Assembly Cdigo MSIL C++.NET Compilador C++ .NET Assembly Cdigo MSIL Componente No Manejado

Cdigo Manejado

Common Language Runtime


Compilador JIT
Cdigo Nativo

Sistema Operativo (Windows)

Modelo de Ejecucin del CLR


Desarrollo
Assembly Instalacin

Instalacin
Assembly en la mquina destino
Policy
<?xml version="1.0" encoding="utf-8" ?> <configuration> <mscorlib> <security> <policy> <PolicyLevel version="1"> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="Nothing" Name="All_Code" Description="Code group grants no permissio ns and forms the root of the code group tree."> <IMembershipCondition clas s="AllMembershipCondition" version="1"/> <CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust"

Ejecucin
Compilador JIT

Class Loader

Seguridad

Assembly Loader Garbage Collector

.exe Nativo + Tabla GC

Code Manager

Manejador Excepciones Soporte MultiThread

Debug Engine

COM Interop

.NET Dynamic Programming


IronPython IronRuby C# VB.NET Others

Dynamic Language Runtime


Expression Trees
Python Binder Ruby Binder

Dynamic Dispatch
Object Binder JScript Binder

Call Site Caching


COM Binder

CTS (Common Type System)


Define un conjunto comn de tipos de datos orientados a objetos Todo lenguaje de programacin .NET debe implementar los tipos definidos por el CTS

Todo tipo hereda directa o indirectamente del tipo System.Object Define Tipos de VALOR y de REFERENCIA

La Memoria y los Tipos de Datos


El CLR administra dos segmentos de memoria: Stack (Pila) y Heap (Montn) El Stack es liberado automticamente y el Heap es administrado por el GC (Garbage Collector)

Los tipos VALOR se almacenan en el Stack

Los tipos REFERENCIA se almacenan en el Heap

{Conociendo el Lenguaje C Sharp}

Microsoft .NET

Sergio Andrs Vargas A. MCTSMCS- MCT-MCP OCP - OCA


Twitter Facebook Blog IM serandvaraco http://www.facebook.com/unespacioparanet http://unespacioparanet.appfuture.net serandvaraco@hotmail.com

VB.NET y C# - Terminacin de lnea


C#: la lnea finaliza con un ;
//Una linea con mas de un renglon string nombre = primerNombre + apellido; //El punto y coma indica FINAL de linea

VB.NET: la lnea finaliza con un salto de lnea


'Una linea con mas de un renglon Dim nombre As String = primerNombre & _ apellido

VB.NET y C# - Declaracin de Bloques


En C# los bloques se declaran entre llaves
class MainClass{ public static void Main(string[] args) { Console.WriteLine("Hello World!"); } }

En VB.NET cada bloque tiene su sentencia de apertura y su sentencia de cierre, que normalmente empieza con la palabra End
Class Main Public Shared Sub Main() Console.WriteLine("Hello World!") End Sub End Class

VB.NET y C# - Comentarios
C# soporta tres tipos de comentarios
string nombre = Juan; // Comentario de una sola lnea /* Comentario con mas de una lnea*/ /// <summary> /// Documentacin XML que puede ser consumida por otras /// herramientas para mostrar ayuda dinmica o generar /// documentacin en varios formatos /// </summary> public class Matematica { /// <summary> /// Calcula la suma de dos nmeros enteros /// </summary> /// <param name="x">El primer operando de la suma</param> /// <param name="y">El segundo operando de la suma</param> /// <returns> La suma entera de ambos operandos</returns> public int Sumar (int x, int y) {return x + y;} }

VB.NET y C# - Case Sensitivity


C# distingue entre maysuclas y minsculas
system.console.writeline(HOLA); INCORRECTO System.Console.WriteLine(HOLA); CORRECTO

VB.NET no distingue entre maysuclas y minsculas


system.console.writeline(HOLA) CORRECTO
System.Console.WriteLine(HOLA) CORRECTO

Tipos de Datos
Categora Enteros Byte SByte Int16 Int32 Clase Un entero sin signo (8-bit) Un entero con signo (8-bit) Un entero con signo (16-bit) Un entero con signo (32-bit) Descripcin C# Alias byte sbyte short int VB.NET Alias Byte Sbyte Short Integer

Int64
Punto Flotante Single Double Decimal Lgicos Otros Boolean Char Object String

Un entero con signo (64-bit)


Un nmero de punto flotante de simple precisin (32-bit) Un nmero de punto flotante de doble precisin (64-bit) Un nmero decimal de 96-bit Un valor booleano (true o false) Un caracter Unicode (16-bit) La raz de la jerarqua de objetos Una cadena de caracteres unicode inmutable y de tamao fijo

long
float double decimal bool char object string

Long
Single Double Decimal Boolean Char Object String

VB.NET y C# - Alcance de miembros


Miembro: se refiere a los campos, propiedades, mtodos, eventos, clases anidadas, etc.
C#: todo miembro es declarado como PRIVATE por default VB.NET: todo miembro es declarado como PUBLIC por default

Modificadores de acceso disponibles:

C# public private internal protected protected internal

VB.NET Public Private Friend Protected Protected Friend

VB.NET y C# - Declaracin de Variables


C#: el tipo de dato precede al identificador (nombre)
int x; decimal y; rectangle z; Cliente cli;

VB.NET: comienza con Dim o algn modificador de acceso (Public, Private, etc.) + identificador de la variable + As Tipo de Dato
Dim Dim Dim Dim x As Integer y As Decimal z As Rectangle cli As Cliente Dim es = a Private por defecto

VB.NET y C# - Inicializacin de Variables


C#: toda variable debe ser inicializada EXPLICITAMENTE antes de ser usada
int tempBalance; //variable local //ERROR: tempBalance NO ha sido inicializada System.Console.WriteLine(tempBalance);

VB.NET: inicializa automticamente las variables en CERO o en Nothing


Dim tempBalance As Integer 'SIN ERROR: tempBalance vale CERO System.Console.WriteLine(tempBalance)

VB.NET y C# - Conversiones de Tipos


C# no permite conversiones implcitas de tipos
Si falla el cast se devuelve null o InvalidCastException
Cuenta CtaCte CtaCte CtaCte cta = new CtaCte(); cc = cta; //Error: puede que cta no sea una CtaCte cc = (CtaCte)cta; //Conversion explicita CASTING cc = cta as CtaCte; //Usando el operador as

if (cta is CtaCte) ... //Comp. con el operador is

VB.NET usa las directivas del compilador Option Strict


Si falla el cast siempre se genera una InvalidCastException
Dim cta As Cuenta = New CtaCte() Dim cc As CtaCte = cta OK Option Strict Off Dim cc As CtaCte = CType(cta, CtaCte) Option Strict On If TypeOf cta Is CtaCte Then Comp. con TypeOf Is

VB.NET y C# - Arreglos
C# utiliza corchetes [ ] para definicin de arrays
string[] telefonos; //Definicion de un Arreglo de strings telefonos = new string[3]; //De 3 elementos telefonos[0] = 1245; //Seteo del 1er elemento del arreglo //Definicion y asignacion de una vez telefonos = new string[] {1,2,3};

VB.NET permite definir arrays de varias formas con ()


Dim telefonos As String() Dim telefonos() As String Dim telefonos(3) As String Crea un array de 4 elementos telefonos(0) = 1245 Seteo del 1er elemento del arreglo Definicion y asignacion de una vez Dim telefonos() As String = {1,2,3}

C# - Matrices
C# utiliza corchetes [,] para definicin de matrices

string[,] Nombres; //Definicion de un Matriz de strings Nombres = new string[2,2]; //De 2X2 elementos Nombres[0,0] = Sergio; //Seteo del 1er elemento de la primera columna Nombres[0,1] = Vargas; //Seteo del 1er elemento de la segunda columna

VB.NET y C# - Operadores
Descripcin Asignacin Adicin Sustraccin Multiplicacin Divisin Negacin Mdulo (Parte entera de la divisin) Mayor Menor Mayor o Igual C# = + * / ! % > < >= VB.NET = + * / not mod > < >=

Menor o Igual

<=

<=

VB.NET y C# - Operadores Lgicos


C# VB.NET Operador
Operador logico Y Operador logico O Negacion logica
Igual Distinto

&& ll ! == !=

And Or Not = <>

En C# todas las evaluaciones se hacen por cortocircuito


//Si Hacer1() es True, entonces //NO se evalua Hacer2() if (Hacer1() || Hacer2()) { } //Si Hacer1() es False, entonces //NO se evalua Hacer2() if (Hacer1() && Hacer2()) { }

En VB.NET se debe utilizar los operadores AndAlso y OrElse


Si Hacer1() es True, entonces NO se evalua Hacer2() If Hacer1() OrElse Hacer2() Then ... End If Si Hacer1() es False, entonces NO se evalua Hacer2() If Hacer1() AndAlso Hacer2() Then ... End If

VB.NET y C# - Sentencias condicionales


C#: sentencia if con varios formatos
if (x > 10) HacerAlgo(); if (x < 10) { Hacer1(); Hacer2(); } if (x < 10) { Hacer1(); } else { Hacer2(); } if (x < 10) { Hacer1(); } else if (x > 20) { Hacer2(); } else { Hacer3(); }

VB.NET: la sentencia If requiere de la palabra Then


If x > 10 Then Hacer() If x < 10 Then Hacer1() Hacer2() End If If x < 10 Then Hacer1() Else Hacer2() End If If x < 10 Then Hacer1() ElseIf x > 20 Then Hacer2() Else Hacer3() End If

VB.NET y C# - Sentencias condicionales


C#: sentencia case
int a = 0; switch(a) { case 1:{//CODIGO 1 break; } case 2: {//CODIGO 2 break; } default:{//CODIGO DEFAULT break; } }

VB.NET: sentencia case


Dim a As Integer = 0 Select a Case 1 'Cdigo 1 Case 2 'Cdigo 2 Case Else 'Cdigo Default End Select

VB.NET y C# - Sentencia for


C#: la sentencia for consta de tres partes
//Partes: declaracin, prueba, accin for (int i=1; i < 10; i++) { }

VB.NET usa las palabras claves For, To, Next y Step


Dim i As Integer For i = 1 To 100 i se incrementa en 1 Next For i = 1 To 100 Step 2 i se incrementa en 2 Next

VB.NET y C# - Sentencia for/each


For/Each permite recorrer arreglos y colecciones C#: usa la palabra foreach
string[] nombres = new string[5]; foreach(string auxNombre in nombres) { //auxNombre es de SOLO LECTURA }

VB.NET usa las palabra For Each


Dim nombres(5) As String Dim auxNombre As String For Each auxNombre In nombres auxNombre NO es de SOLO LECTURA Next

VB.NET y C# - Sentencia while


C#:
bool condicion = true; while (condicion == true){ //En algn momento poner condicion = false }

VB.NET:
Dim condicion As Boolean = True While condicion = True 'Poner condicion=false en algn momento End While

Microsoft .NET

{POO}

Sergio Andrs Vargas A. MCTSMCS- MCT-MCP OCP - OCA


Twitter Facebook Blog IM serandvaraco http://www.facebook.com/unespacioparanet http://unespacioparanet.appfuture.net serandvaraco@hotmail.com

VB.NET y C# - Clases
C#: las clases son declaradas mediante class
//Definicion de la clase CuentaBancaria class CuentaBancaria { //Definicion de miembros }

VB.NET usa las palabras Class / End Class


Definicion de la clase CuentaBancaria Class CuentaBancaria Definicion de miembros End Class

Sintaxis Entry Point


C#:
public class HolaMundo { public static void Main(string[] args){ //Punto de entrada de la aplicacin } }

VB.NET
Public Class HolaMundo Public Shared Sub Main(ByVal args() As String) Punto de entrada de la aplicacin End Sub End Class

VB.NET y C# - Mtodos
Mtodos: acciones que un objeto puede llevar a cabo. En C# todo mtodo es una funcin
public void HacerDeposito(int importe) //No devuelve valor { }
public int ObtenerInventario(int codArticulo) //Devuelve un entero { }

VB.NET usa procedimientos Sub y funciones Function


Public Sub HacerDeposito(ByVal importe As Integer) No devuelve valor End Sub

Public Function Inventario(ByVal codArt As Integer) As Integer Devuelve un entero End Function

VB.NET y C# - Constructores
Constructor: mtodos dentro de la clase que son llamados automticamente cuando se crea una instancia de dicha clase.
En C# tienen el mismo nombre de la clase
class CtaCte { public CtaCte(){...} public CtaCte(int i){...} }

//Const. por default //Const. con un parametro

VB.NET usa un procedimiento Sub New


Class CtaCte Sub New() End Sub Sub New(ByVal i As Integer) End Sub End Class

VB.NET y C# - Sobrecarga de Mtodos


Sobrecarga: varios mtodos con el mismo nombre pero diferente firma.
C#
public void HacerDeposito(int importe) { } public void HacerDeposito(int importe, bool acreditar) { }

VB.NET
Public Sub HacerDeposito(ByVal imp As Integer) End Sub Public Sub HacerDeposito(ByVal imp As Integer, ByVal acreditar As Boolean) End Sub

VB.NET y C# - Mtodos estticos


Miembros que no requieren de una instancia para ser invocados. Se los llama mtodos de clase C#
public static void HacerDeposito(int importe) { }

VB.NET
Public Shared Sub HacerDeposito(ByVal imp As Integer)
End Sub

VB.NET y C# - Propiedades
Propiedad: caracterstica o atributo de un objeto
C#
class CtaCte { int balance; public int Balance { get { return balance; } set { balance = value; } } } CtaCte cc = new CtaCte(); cc.Balance = 100; //Asignacin Mostrar(cc.Balance); //Obtencin

VB.NET
Class CtaCte Dim _balance As Integer Property Balance() As Integer Get Return _balance End Get Set (ByVal value As Integer) _balance = value End Set End Property End Class Dim cc As New CtaCte() cc.Balance = 100 Asignacin Mostrar(cc.Balance) Obtencin

VB.NET y C# - Herencia
En C# la herencia se define:
class Cuenta { } class CtaCte : Cuenta { } //Clase Base

//Clase Derivada

VB.NET usa la palabra clave Inherits


Class Cuenta End Class
Class CtaCte Inherits Cuenta End Class

Clase Base

En .NET solo se permite Herencia Simple

Clase Derivada

VB.NET y C# - Herencia (Cont.)


En C#
public sealed class Cuenta{ //No se puede heredar de esta clase sellada } public abstract class Cuenta{ //No se pueden crear instancias de esta clase, slo //de sus derivadas }

VB.NET
Public NotInheritable Class Cuenta No se puede heredar de esta clase End Class

Public MustInherit Class Cuenta No se pueden crear instancias de esta clase, slo de sus derivadas End Class

VB.NET y C# - Namespaces
C#
namespace BancoARG { namespace Gestion { public class CtaCte { } public class CajaAhorro { } } } //Referencia full BancoARG.Gestion.CtaCte; BancoARG.Gestion.CajaAhorro; //Referencia corta using BancoARG.Gestion; CtaCte cc = new CtaCte(); CajaAhorro ca = new CajaAhorro();

VB.NET
Namespace BancoARG Namespace Gestion Public Class CtaCte End Class Public Class CajaAhorro End Class End Namespace End Namespace Referencia full BancoARG.Gestion.CtaCte BancoARG.Gestion.CajaAhorro Referencia a un namespace Imports BancoARG.Gestion Dim cc As New CtaCte() Dim ca As New CajaAhorro()

VB.NET y C# - Admin. De Excepciones


Excepcin: condicin anmala de funcionamiento de una aplicacin C#: usa las palabras try/catch/finally
try { int resultado = x/y; } catch(DivideByZeroException e) { //Error division por cero } catch { //Otro error } finally { //Siempre pasa por aca }

VB.NET usa las palabras Try/Catch/Finally

Try Dim resultado As Integer resultado = x/y Catch e As DivideByZeroException Error division por cero Catch Otro error Finally Siempre pasa por aca End Try

Microsoft .NET

{Generics}

Sergio Andrs Vargas A. MCTSMCS- MCT-MCP OCP - OCA


Twitter Facebook Blog IM serandvaraco http://www.facebook.com/unespacioparanet http://unespacioparanet.appfuture.net serandvaraco@hotmail.com

permiten definir estructuras de datos de seguridad de tipos, sin comprometerse a tipos de datos reales.

Colecciones Genricas
List<t> Dictionary<a,b> Seek<t> Queek<t>

Listas

Arreglos

2008 Microsoft Corporation. Todos los derechos reservados. Microsoft, Windows, Windows Vista y otros nombres de producto son y pueden ser marcas registradas y registros en Estados Unidos y en otros pases. La informacin contenida en el presente es slo para fines informativos y representa la visin actual de Microsoft Corporation a la fecha de esta presentacin. Debido a que Microsoft debe responder a las cambiantes condiciones del mercado, no se debe interpretar como un compromiso por parte de Microsoft, y Microsoft no puede garantizar la precisin de ninguna informacin provista despus de la fecha de esta presentacin. MICROSOFT NO OFRECE GARANTA ALGUNA, EXPRESA, IMPLCITA O DE LEY, RESPECTO A LA INFORMACIN EN ESTA PRESENTACIN.

68

Recursos para los desarrolladores

http://microsoft.com/spanish/msdn/latam/mediacenter/
Microsoft MSDN Latinoamrica te ofrece los ltimos recursos multimedia en espaol para desarrolladores: presentaciones y demostraciones en directo o diferido, va Internet, brindadas por expertos de Microsoft, las cuales te ayudarn a mantenerte al da con informacin sobre los productos y tecnologas que utilizas a diario en el desarrollo de tus aplicaciones.

Preguntas

También podría gustarte