Mostrando entradas con la etiqueta .net. Mostrar todas las entradas
Mostrando entradas con la etiqueta .net. Mostrar todas las entradas

Cómo leer archivos planos con ADO.NET (versión Visual Basic 2005)

jueves 13 de diciembre de 2007 | categorías: , , , , | 4 comentarios -- da clic aquí para dejar el tuyo

Hace poco más de un año escribí este artículo que describe una técnica para leer archivos planos utilizando el OleDB provider de ADO.NET.  Es uno de los artículos de este sitio que ha recibido más comentarios, y entre ellos está uno que dejó fredy que me hizo re-hacer el ejemplo en Visual Basic 2005 para comprobar que no fuera un error de código—en realidad él hizo la mayor parte de la chamba para "traducir" la rutina.

No voy a explicar mucho la lógica del código—para eso te dejo de tarea que leas el artículo original—aquí simplemente te comparto cómo se vería la rutina en VB:

Imports System.IO
Imports System.Data
Imports System.Data.OleDb
 
Module Utilerias
   Public Enum TipoDeArchivoPlano
        Delimited
        Fixed
   End Enum
 
   Public Function LeerArchivoPlano(ByVal archivo As FileInfo, _
        ByVal tieneEncabezado As Boolean, _
        ByVal tipoDeArchivo As TipoDeArchivoPlano) As DataTable
 
        If (Not archivo.Exists) Then
            Throw New FileNotFoundException("No se encontró el archivo especificado")
        End If
 
        Dim conEncabezado As String = IIf(tieneEncabezado, "YES", "NO")
 
        Dim connectionString As String = _
            String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};" + _
            "Extended Properties='text;HDR={1};FMT={2}'", _
            archivo.DirectoryName, conEncabezado, tipoDeArchivo.ToString())
 
        Dim dt As DataTable = New DataTable("miTabla")
 
        Using conn As OleDbConnection = New OleDbConnection(connectionString)
            Using da As OleDbDataAdapter = New OleDbDataAdapter( _
               "SELECT * FROM " + archivo.Name, conn)
 
               da.Fill(dt)
            End Using
        End Using
 
        Return dt
   End Function
End Module

Para probarla, hice una aplicación sencilla en ASP.NET que mostrara los datos de un archivo .CSV que está dentro de un subdirectorio del sitio web.

El archivo jason.csv contiene:

Producto,Cantidad,Precio
Sierra eléctrica,1,250
Máscara de hockey,1,15.50
Machete,5,2.70
Detergente para ropa (con quita-manchas),1,10
Delantal,2,7.25
Afilador,3,5

La página dentro de la solución que en realidad solo tiene un GridView.  Este es el contenido de Default.aspx:

<%@ Page Language="VB" AutoEventWireup="false" 
   CodeFile="Default.aspx.vb" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
   <title>Leer un archivo plano con VB 2005</title>
</head>
<body>
   <form id="miFormulario" runat="server">
   <div>
        <asp:GridView ID="miGridView" runat="server">
        </asp:GridView>
   </div>
   </form>
</body>
</html>

Finalmente, para mandar llamar la rutina y bindear—¿enlazar?—los datos al GridView, solo agregué esto en el code-behind:

Partial Class _Default
   Inherits System.Web.UI.Page
 
   Protected Sub miFormulario_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles miFormulario.Load
 
        If Not Page.IsPostBack Then
            Dim archivo As FileInfo = _
               New FileInfo("D:\WebSites\LeerArchivosPlanosVB\Archivos\jason.csv")
 
            Dim tabla As New DataTable
            tabla = Utilerias.LeerArchivoPlano(archivo, True, TipoDeArchivoPlano.Delimited)
 
            If tabla.Rows.Count > 0 Then
               miGridView.DataSource = tabla
               miGridView.DataBind()
            Else
               Response.Write("No hay datos para mostrar.")
            End If
 
        End If
   End Sub
End Class

El resultado de correr la página:

 

Whew! Funcionó smile_teeth

Enjoy. smile_shades


PD.  Puedes descargar el código de este ejemplo del sitio de la Comunidad .NET de Cd. Juárez.

¿Ya estás listo para Visual Studio 2008?

martes 6 de noviembre de 2007 | categorías: , , | 0 comentarios -- da clic aquí para dejar el tuyo

Con el anuncio ayer que hizo Microsoft de que Visual Studio 2008 y el .NET Framework 3.5 estarán disponibles para suscriptores de MSDN a finales de este mes (can you say: wohoo! thumbs_up) es hora de comenzar a prepararse para varias novedades que trae.Tecnologías en las diferentes versiones del .NET Framework

En lo personal me tiene emocionado el lanzamiento porque creo que le agregaron cosas que ya urgían.  Comenzando por el soporte nativo a las tecnologías de .NET 3.0 y ASP.NET AJAX—no más andar instalando extensiones y adiciones por separado.  Por ejemplo, me acaban de dar una máquina nueva en el trabajo, y solo de Visual Studio tuve que instalar:  Visual Studio 2005, Visual Studio 2005 SP1, .NET 3.0 Framework Runtime, Windows SDK February 2007 update, Visual Studio Extensions for WCF & WPF November 2006 CTP (que no funciona muy bien), Visual Studio Extensions for WF, ASP.NET AJAX y ASP.NET AJAX Control Toolkit.  Cuéntalas: OCHO cosas que se reducirán a uno o dos.

Además, finalmente le agregaron soporte decente para CSS y un editor y debuggeador de JavaScript excelente, lo cual es música para los oídos de desarrolladores web como yo.

"¡Pero aún hay más!", como dirían los vendedores: LINQ—una tecnología que promete cambiar cómo lidean los programadores con el acceso a datos, sin tener que salirse del paradigma de C# o VB—, soporte para Silverlight y más (whew!).

En fin, como una imágen dice más que mil palabras, aquí está un poster (PDF) que pueden descargar e imprimir de los tipos y espacios de nombre más comúnes con .NET 3.5.

Además, el 14 de noviembre—¡osea en menos de dos semanas!—tendremos en Ciudad Juárez el Tour Tecnológico 2007 de Microsoft.  Este es un evento como el CodeCamp que tuvimos en abril de este año o el Community Dev Day del año pasado así que no te lo pierdas. 

Tour Tecnológico Microsoft 2007

La agenda es:
8:30  Registro
8:45 Bienvenida
9:00 
Características principales de VS 2008 y el .Net framework 3.5
10:00 Construyendo Clientes inteligentes usando Visual Studio 2008, WPF y Expression Blend
11:00 Receso
11:30 Construyendo aplicaciones móviles usando Visual Studio 2008 y el .NET Compact Framework 3.5
12:30 Introducción al ciclo de desarrollo con Visual Studio Team System

Para registrarte ve a esta dirección: http://www.mslatam.com/spanish/msdn/mexico/tour2007/ luego selecciona Lista de Eventos > Chihuahua > Cd. Juárez.

OJO, que en esta ocasión el evento será en uno de los edificios de la UACJ (el que está por la Avenida del Charro), NO será en el Tec de Monterrey, donde normalmente tenemos las reuniones y eventos.

Espero verlos ahi. smile_wink

Actualización, 6 Noviembre 2007, 10:56AM:

Acabo de recibir un correo que la agenda cambió.  Esta es la nueva agenda:

8:30      Registro
8:45      Bienvenida
9:00      Características principales de VS 2008 y el .Net Framework 3.5
9:45      Construyendo Clientes inteligentes usando Visual Studio 2008, WPF y Expression Blend
10:30   Receso
11:00   Construyendo aplicaciones móviles usando Visual Studio 2008 y el .NET Compact Framework 3.5
11:45  Introducción al ciclo de desarrollo con Visual Studio Team System
12:30   Desarrollo de aplicaciones interactivas con Windows Live
1:00     Interoperabilidad de documentos con OpenXML

Ya están disponibles las presentaciones y archivos de ASP.NET

lunes 5 de noviembre de 2007 | categorías: , , , | 0 comentarios -- da clic aquí para dejar el tuyo

Ya tenía un buen sin poder escribir por andar con las carreras del trabajo, pero de alguna forma tuve tiempo de dar el tema y el taller del mes de Septiembre y de Octubre de la Comunidad, donde el tema fue, primero ASP.NET "para novatos", y luego ASP.NET "intermedio".

El primer tema surgió, porque había muchas personas interesadas en comenzar a aprender ASP.NET pero que solo necesitaban una orientada de por dónde empezar.  Así que ese fue el espíritu de la reunión.  Vimos los conceptos fundamentales, basicotes pero necesarios para que entendieran qué estaba sucediendo.  Vimos algunos de los controles básicos, manejo de eventos, y hasta algo de DataBinding con controles como el GridView y DetailsView para hacer una página maestro/detalle.  Para la presentación tomé prestadas algunas de las diapositivas del material que viene en el Desarrollador Cinco Estrellas (que la verdad está excelente), pero le agregué algunas otras ilustraciones que a mi me ayudaron mucho.  Eventualmente, si Diosito me da licencia lo convertiré en uno o dos artículos para este blog porque el rollo que mareador que yo tiro no sale en los archivos jejeje.

 

Como la gente se quedó "picada", votaron por un tema "intermedio".  Así que en la siguiente reunión les platiqué acerca de controles de usuario (user controls), que son controles compuestos a partir de otros controles, de Master Pages, que es una manera de aplicar elementos comunes a todo tu sitio y también sobre todo el armazón de seguridad que agregaron con ASP.NET 2.0.  Escogí esos temas porque creo que son de los más útiles y prácticos en la chamba del día a día.  En el taller vimos con detalle y calma cómo instalar la base de datos de membresía, cómo aplicar seguridad a diferentes áreas del sitio y cómo utilizar todos los controles de membresía y navegación que vienen con Visual Studio.

En fin, me divertí bastante.  Si no pudiste asistir, aún puedes descargar las presentaciones y las soluciones de los talleres desde área de descargas del sitio de la Comunidad.

Enjoy.

Lo que todo desarrollador debería saber sobre serialización a XML en .NET (y cómo afecta a los Web Services)

lunes 23 de abril de 2007 | categorías: , , , , | 6 comentarios -- da clic aquí para dejar el tuyo

En la plática y taller de este mes, alguien hizo una pregunta muy común: "Quiero construir un Web Service en .NET que haga X, ¿por dónde comienzo?"

Así que le prometí escribir un artículo al respecto. Sin embargo, en cuanto comencé, me di cuenta que hay un concepto más básico que debe ser amaestrado para en verdad entender lo que está sucediendo: Serialización. Específicamente serialización a XML.

¿Qué es serialización y cómo se utiliza?

Serialización, no es más que una palabra dominguera que significa transformar una instancia de una clase a una serie de bytes con un formato determinado. En este caso estoy hablando de agarrar una instancia de una clase y transformarla a un documento XML.

En la plática, algunas personas se sorprendieron cuando les dije que prácticamente cualquier clase podía ser serializada casi automáticamente, de una manera relativamente sencilla. Solo hay un "pero" del que debes estar consciente: únicamente los miembros y propiedades públicas pueden ser serializados. En otras palabras, no convierte métodos, indexadores, campos privados o protegidos o propiedades solo-lectura (excepto colecciones solo-lectura).

Toma como ejemplo una clase sencilla como la siguiente:

using System;
 
public class MiClase
{
    protected string _campo1 = "campo1 es protegido";
    public string _campo2 = "campo2 es publico";
    private string _campo3 = "campo3 es privado";
    private int _propiedad1 = 1000;
    private int _propiedad2 = 9999;
    public int _propiedad3 = 7777;
 
    public int UnaPropiedad
    {
        get { return _propiedad1; }
        set { _propiedad1 = value; }
    }
 
    protected int OtraPropiedad
    {
        get { return _propiedad2; }
        set { _propiedad2 = value; }
    }
 
    public int PropiedadPublica
    {
        get { return _propiedad3; }
    }
 
    // Se requiere un constructor publico default para que 
    // funcione la serializacion
    public MiClase() { }
}

Podemos serializarla (transformarla a XML pues) con un código como este:

using System;
using System.IO;
using System.Xml.Serialization;
 
class Program
{
    static void Main(string[] args)
    {
        MiClase m = new MiClase();
 
        XmlSerializer serializador = new XmlSerializer(typeof(MiClase));
        StringWriter escritor = new StringWriter();
 
        // se puede serializar a casi cualquier tipo de Stream o Writer
        // p.ej. System.IO.StreamWriter, System.Xml.XmlWriter, etc.
        serializador.Serialize(escritor, m);
        Console.WriteLine(escritor.ToString());
    }
}

Si corremos el programa, el resultado será este:

O, visto de una manera más amigable (utilizando el visualizador de XML de Visual Studio):

Nota que únicamente el _campo2, _propiedad3 y UnaPropiadad fueron serializados, ya que eran los únicos con un nivel de acceso public. PropiedadPublica, a pesar de ser public, era solo-lectura y por lo tanto no fue serializada. También nota que automáticamente construyó el documento utilizando el nombre de la clase (MiClase) como el elemento raíz y tomó el nombre de cada campo para los elementos hijos (_campo2, _propiedad3, UnaPropiedad).

La magia la hace la clase XmlSerializer, la cual tiene 3 métodos interesantes:

  • Serialize() convierte una instancia de una clase a XML.
  • Deserialize() hace lo contrario, toma un documento XML y lo transforma en una instancia de una clase.
  • CanDeserialize() regresa un booleano para probar si el XML en realidad se puede des-serializar.

Ahora, puedes controlar varios aspectos de la serialización, aplicando atributos:

  • [Serializable] no solo indica que la clase puede ser serializada, sino que también revisa que todos los tipos contenidos dentro de la clase (otra clase, por ejemplo) también sean serializables. Si no lo son, entonces arroja un SerializationException.
  • [NonSerialized] y [XmlIgnore] indican que no queremos que se serialize el campo o propiedad. El primero afecta al SoapFormatter (el utilizado por WebServices), y el segundo afecta a XmlSerializer.
  • [XmlRoot], que su vez tiene parámetros como Namespace y ElementName para especificar el nombre y espacio de nombres del elemento raíz. Este se aplica solo a la clase.
  • [XmlElement], es parecido al anterior, pero se aplica a los campos o propiedades. Puedes especificar el tipo de dato de XML Schema que debe aplicar y si es o no nulleable mediante los parámetros DataType y IsNullable. También puedes especificar el espacio de nombres y el nombre del elemento como en XmlRoot.
  • [XmlAttribute] indica que quieres serializar el valor como un atributo, en lugar de un elemento.

Para ver el impacto, vamos a aplicar estos conceptos al ejemplo anterior:

using System;
using System.Xml.Serialization;
 
[Serializable()]  //indica explicitamente que esta clase es serializable
[XmlRoot(Namespace = "http://comunidadnetjuarez.org/2007/04",
    ElementName = "MiClaseSerializada")] // indica el namespace y nombre 
public class MiClase                     // del elemento raiz
{
    protected string _campo1 = "campo1 es protegido";
 
    [XmlElement(ElementName = "SegundoCampo",
        DataType = "string",
        IsNullable = false)]  // indica el nombre y tipo del elemento
    public string _campo2 = "campo2 es publico";
 
    private string _campo3 = "campo3 es privado";
    private int _propiedad1 = 1000;
    private int _propiedad2 = 9999;
 
    [NonSerialized()] // no serializar cuando se use SoapFormatter
    [XmlIgnore()]     // no serializar cuando se use XmlSerializer
    public int _propiedad3 = 7777;
 
    [XmlAttribute(AttributeName = "valor")] // indica que deseamos que
    public int UnaPropiedad                 // se serialize como atributo XML
    {                                       // y no como elemento XML
        get { return _propiedad1; }
        set { _propiedad1 = value; }
    }
 
    protected int OtraPropiedad
    {
        get { return _propiedad2; }
        set { _propiedad2 = value; }
    }
 
    public int PropiedadPublica
    {
        get { return _propiedad3; }
    }
 
    // Se requiere un constructor publico default para que 
    // funcione la serializacion
    public MiClase() { }
}

El resultado sería el siguiente:

La cosa comienza a ponerse más interesante mientras más complejidad le agreguemos a la clase. Por ejemplo, ¿qué pasa si mi clase tiene una colección o lista de cosas? Bueno, pues resulta que únicamente las colecciones que implementen ICollection o IEnumerable podrán serializarse (p.ej. un ArrayList). Si implementan IDictionary (como un HashTable) estas no son serializadas (de hecho levanta una excepción).

Agreguemos el siguiente miembro a la clase:

    public string[] arreglo = { "arreglo uno", 
                                "arreglo dos", 
                                "arreglo tres" };

El resultado sería el siguiente:

Y finalmente veamos qué pasa si aplicamos [XmlElement]:

    [XmlElement(ElementName = "UnArreglo")]
    public string[] arreglo = { "arreglo uno", 
                                "arreglo dos", 
                                "arreglo tres" };

Creación automática de una clase serializable

Como puedes ver, tienes bastante control sobre la conversión de una clase .NET a un documento XML. Sin embargo, mientras más complejo sea el documento XML que quieras producir, más complejo y cuidadoso tendrás que ser con la aplicación de los atributos para obtener el resultado que quieres.

Muchas veces quizá es más sencillo comenzar con un documento XML de ejemplo o mejor aún con el contrato XML Schema que debe cumplir el documento XML que quieres producir cuando se serialice tu clase. Una vez que tienes esto, puedes utilizar la utilería xsd.exe para automáticamente generar los tipos adecuados en C# (o VB.NET).

Veamos un ejemplo. Supongamos que tienes un archivo llamado SchemaEjemplo.xsd con el siguiente contenido:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="personas">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="persona"
                    type="personaType"
                    minOccurs="1"
                    maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="personaType">
    <xs:sequence>
      <xs:element name="titulo"
                  type="tituloType"
                  minOccurs="0" />
      <xs:element name="nombre"
                  type="nombreType" />
      <xs:element name="edad"
                  type="xs:integer" />
      <xs:element name="direccion"
                  type="direccionType" />
      <xs:element name="genero"
                  type="generoType" />
    </xs:sequence>
    <xs:attribute name="colorOjos"
                  type="xs:string" />
  </xs:complexType>
  <xs:simpleType name="tituloType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Sr." />
      <xs:enumeration value="Sra." />
      <xs:enumeration value="Señorita" />
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="direccionType">
    <xs:sequence>
      <xs:element name="calle"
                  type="xs:string" />
      <xs:element name="numero"
                  type="xs:string" />
      <xs:element name="numeroDepartamento"
                  type="xs:string"
                  minOccurs="0" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="nombreType">
    <xs:all>
      <xs:element name="primerNombre"
                  type="xs:string" />
      <xs:element name="segundoNombre"
                  type="xs:string"
                  minOccurs="0" />
      <xs:element name="apellidos"
                  type="xs:string" />
    </xs:all>
  </xs:complexType>
  <xs:complexType name="generoType">
    <xs:choice>
      <xs:element name="hombre"
                  type="xs:boolean" />
      <xs:element name="mujer"
                  type="xs:boolean" />
    </xs:choice>
  </xs:complexType>
</xs:schema>

La siguiente línea de comando de Visual Studio 2005 genera las clases necesarias:

xsd.exe SchemaEjemplo.xsd /classes /language:CS

El archivo resultante (SchemaEjemplo.cs) se ve algo así como este (solo muestro una parte dado que es muy largo el fragmento de código). Nota que define una clase fuertemente tipada por cada elemento o complexType definido en el Schema:

//------------------------------------------------------------------------------
// 
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// 
//------------------------------------------------------------------------------
 
using System.Xml.Serialization;
 
// 
// This source code was auto-generated by xsd, Version=2.0.50727.42.
// 
 
 
/// 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class personas
{
 
    private personaType[] personaField;
 
    /// 
    [System.Xml.Serialization.XmlElementAttribute("persona", 
        Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public personaType[] persona
    {
        get { return this.personaField; }
        set { this.personaField = value; }
    }
}
 
/// 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class personaType
{
 
    private tituloType tituloField;
    private bool tituloFieldSpecified;
    private nombreType nombreField;
    private string edadField;
    private direccionType direccionField;
    private generoType generoField;
    private string colorOjosField;
 
    /// 
    [System.Xml.Serialization.XmlElementAttribute(
        Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public tituloType titulo
    {
        get { return this.tituloField; }
        set { this.tituloField = value; }
    }
 
    /// 
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool tituloSpecified
    {
        get { return this.tituloFieldSpecified; }
        set { this.tituloFieldSpecified = value; }
    }
 
    /// 
    [System.Xml.Serialization.XmlElementAttribute(
        Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public nombreType nombre
    {
        get { return this.nombreField; }
        set { this.nombreField = value; }
    }
 
    /// 
    [System.Xml.Serialization.XmlElementAttribute(
        Form = System.Xml.Schema.XmlSchemaForm.Unqualified, DataType = "integer")]
    public string edad
    {
        get { return this.edadField; }
        set { this.edadField = value; }
    }
 
    /// 
    [System.Xml.Serialization.XmlElementAttribute(
        Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public direccionType direccion
    {
        get { return this.direccionField; }
        set { this.direccionField = value; }
    }
 
    /// 
    [System.Xml.Serialization.XmlElementAttribute(
        Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public generoType genero
    {
        get { return this.generoField; }
        set { this.generoField = value; }
    }
 
    /// 
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string colorOjos
    {
        get { return this.colorOjosField; }
        set { this.colorOjosField = value; }
    }
}
 
// ... así continúa ...

Una vez que tus clases han sido generadas es solo cuestión de utilizarlas:

using System;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
 
class Program
{
    static void Main(string[] args)
    {
        // objeto principal
        personas p = new personas();
 
        // declara dos personas
        personaType p1 = new personaType();
        personaType p2 = new personaType();
 
        // poner las propiedades de p1
        p1.colorOjos = "Cafe";
 
        direccionType d1 = new direccionType();
        d1.calle = "Chinches Bravas";
        d1.numero = "123";
        d1.numeroDepartamento = "";
        p1.direccion = d1;
 
        p1.edad = "25";
 
        generoType g1 = new generoType();
        g1.ItemElementName = ItemChoiceType.hombre;
        g1.Item = true;
        p1.genero = g1;
 
        nombreType n1 = new nombreType();
        n1.primerNombre = "Chucho";
        n1.segundoNombre = "El";
        n1.apellidos = "Roto";
        p1.nombre = n1;
 
        p1.titulo = tituloType.Sr;
 
        // poner las propiedades de p2
        p2.colorOjos = "Azul";
 
        direccionType d2 = new d