Sorteo Libros Krasis Press
 
Enviar a un amigo Imprimir Texto sin justificar Texto justificado Letra pequeña Letra mediana Letra grande
buscar 
novedades
Recibe las ultimas noticias y los mejores articulos en tu email
Secciones
 • .NET Framework
 • ADO .NET
 • Ajax
 • Asp .NET
 • Biztalk
 • C#
 • Commerce Server
 • Exchange
 • IIS
 • Metodologías
 • J#
 • Móviles
 • Office
 • Reporting Services
 • Seguridad
 • Servicios Web
 • Sharepoint
 • Silverlight
 • SQL Server
 • Visual Basic .NET
 • Visual C++ .NET
 • Visual Studio
 • WCF
 • Windows
 • Workflow Foundation
 • WPF
 • XAML
 • XML
 • Dynamics
 • Libros
 • Noticias
 • Articulos
 • Webcast
 • Tutoriales
 • Eventos
 • Cursos
 • Ofertas Empleo
 • RSS
Contacto
¿Quieres saber quien es el creador de Clikear?
Weblogfree.com, crea tu propio blog facilmente, gratis y en español
Dotnetsolidario, ayuda al tercer mundo a traves de las tecnologias de la informacion
 
 

Tutorial C#

La clase primegenia: System.Object

 

Ahora que sabemos lo que es la herencia es el momento apropiado para explicar que en .NET todos los tipos que se definan heredan implícitamente de la clase System.Object predefinida en la BCL, por lo que dispondrán de todos los miembros de ésta. Por esta  razón se dice que System.Object es la raíz de la jerarquía de objetos de .NET.

 

A continuación vamos a explicar cuáles son estos métodos comunes a todos los objetos:

 

  • public virtual bool Equals(object o): Se usa para comparar el objeto sobre el que se aplica con cualquier otro que se le pase como parámetro. Devuelve true si ambos objetos son iguales y false en caso contrario.

 

La implementación que por defecto se ha dado a este método consiste en usar igualdad por referencia para los tipos por referencia e igualdad por valor para los            tipos por valor. Es decir, si los objetos a comparar son de tipos por referencia sólo se devuelve true si ambos objetos apuntan a la misma referencia en memoria dinámica, y si los tipos a comparar son tipos por valor sólo se devuelve true si todos los bits de ambos objetos son iguales,  aunque se almacenen en posiciones diferentes de memoria.

 

Como se ve, el método ha sido definido como virtual, lo que permite que los programadores puedan redefinirlo para indicar cuándo ha de considerarse que son iguales dos objetos de tipos definidos por ellos. De hecho, muchos de los tipos incluidos en la BCL cuentan con redefiniciones de este tipo, como es el caso de string, quien aún siendo un tipo por referencia, sus objetos se  consideran iguales si apuntan a cadenas que sean iguales carácter a carácter (aunque referencien a distintas direcciones de memoria dinámica)

 

El siguiente ejemplo muestra cómo hacer una redefinición de Equals() de manera que aunque los objetos Persona sean de tipos por referencia, se considere que dos Personas son iguales si tienen el mismo NIF:

 

                        public override bool Equals(object o)

                        {

                                   if (o==null)

                                               return this==null;

                                   else

                                               return (o is Persona) && (this.NIF == ((Persona) o).NIF);

                        }

 

Hay que tener en cuenta que es conveniente que toda redefinición del método Equals() que hagamos cumpla con    una serie de propiedades que muchos de los   métodos incluidos en las distintas clases de la BCL esperan que se cumplan. Estas propiedades son:

 

q       Reflexividad: Todo objeto ha de ser igual a sí mismo. Es decir, x.Equals(x) siempre ha de devolver true.

q       Simetría: Ha de dar igual el orden en que se haga la comparación. Es decir, x.Equals(y) ha de devolver lo mismo que y.Equals(x) .

q       Transitividad: Si dos objetos son iguales y uno de ellos es igual a otro, entonces el primero también ha de ser igual a ese otro objeto. Es decir, si x.Equals(y) e y.Equals(z) entonces x.Equals(z) .

q       Consistencia: Siempre que el método se aplique sobre los mismos objetos ha de devolver el mismo resultado.

q       Tratamiento de objetos nulos: Si uno de los objetos comparados es nulo (null), sólo se ha de devolver true si el otro también lo es.

 

Hay que recalcar que el hecho de que redefinir Equals() no implica que el operador de igualdad (==) quede también redefinido. Ello habría que hacerlo de independientemente como se indica en el Tema 11: Redefinición de operadores.

 

  • public virtual int GetHashCode(): Devuelve un código de dispersión (hash) que representa de forma numérica al objeto sobre el que el método es aplicado. GetHashCode() suele usarse para trabajar con tablas de dispersión, y se cumple que si dos objetos son iguales sus códigos de dispersión serán iguales, mientras que si son distintos la probabilidad de que sean iguales es ínfima.

 

En tanto que la búsqueda de objetos en tablas de dispersión no se realiza únicamente usando la igualdad de objetos (método Equals()) sino usando también la igualdad de códigos de dispersión, suele ser conveniente redefinir  GetHashCode() siempre que se redefina Equals() De hecho, si no se hace el compilador informa de la situación con un mensaje de aviso.

 

  • public virtual string ToString(): Devuelve una representación en forma de cadena del objeto sobre el que se el método es aplicado, lo que es muy útil para depurar aplicaciones ya que permite mostrar con facilidad el estado de los objetos.

 

La implementación por defecto de este método simplemente devuelve una cadena de texto con el nombre de la clase a          la que pertenece el objeto sobre el que es aplicado. Sin embargo, como lo habitual suele ser implementar ToString() en cada nueva clase que es defina, a continuación mostraremos un ejemplo de cómo redefinirlo en la clase Persona para que muestre los valores de todos los campos de los objetos Persona:

 

                        public override string ToString()

                        {

                                   string cadena = “”;

 

                                   cadena += “DNI = “ + this.DNI + ”\n”;

                                   cadena +=”Nombre = ” + this.Nombre + ”\n”;

                                   cadena +=”Edad = ” + this.Edad + ”\n”;

                                  

                                   return cadena;

                        }

 

Es de reseñar el hecho de que en realidad los que hace el operador de concatenación de cadenas (+) para concatenar una cadena con un objeto cualquiera es convertirlo primero en cadena llamando a su método ToString() y luego realizar la concatenación de ambas cadenas.

 

Del mismo modo, cuando a Console.WriteLine() y Console.Write() se les pasa como parámetro un objeto lo que hacen es mostrar por la salida estándar el resultado de convertirlo en cadena llamando a su método ToString(); y si se les pasa como parámetros una cadena seguida de varios objetos lo muestran por la salida estándar esa cadena pero sustituyendo en ella toda subcadena de la forma {<número>} por el resultado de convertir en cadena el parámetro que ocupe la posición <número>+2 en la lista de valores de llamada al método.

 

  • protected object MemberWiseClone(): Devuelve una copia shallow copy del objeto sobre el que se aplica. Esta copia es una copia bit a bit del mismo, por lo que el objeto resultante de la copia mantendrá las mismas referencias a otros que tuviese el objeto copiado y toda modificación que se haga a estos objetos a través de la copia afectará al objeto copiado y viceversa.

 

Si lo que interesa es disponer de una copia más normal, en la que por cada objeto referenciado se crease una copia del mismo a la que referenciase el objeto clonado, entonces el programador ha de escribir su propio método clonador pero puede servirse de MemberwiseClone() como base con la que copiar los campos que no sean de tipos referencia.

 

 

  • public System.Type GetType(): Devuelve un objeto de clase System.Type que representa al tipo de dato del objeto sobre el que el método es aplicado. A través de los métodos ofrecidos por este objeto se puede acceder a metadatos sobre  el mismo como su nombre, su clase padre, sus miembros, etc. La explicación de cómo usar los miembros de este objeto para obtener dicha información queda fuera del alcance de este documento ya que es muy larga y puede ser fácilmente consultada en la documentación que acompaña al .NET SDK.

 

  • protected virtual void Finalize(): Contiene el código que se ejecutará siempre que vaya ha ser destruido algún objeto del tipo del que sea miembro. La implementación dada por defecto a Finalize() consiste en no hacer nada.

 

Aunque es un método virtual, en C# no se permite que el programador lo redefina explícitamente dado que hacerlo es peligroso por razones que se explicarán en el Tema 8: Métodos (otros lenguajes de .NET podrían permitirlo).

 

Aparte de los métodos ya comentados que todos los objetos heredan, la clase System.Object también incluye en su definición los siguientes métodos de tipo:

 

·        public static bool Equals(object objeto1, object objeto2) à Versión  estática del método Equals() ya visto. Indica si los objetos que se le pasan como parámetros son iguales, y para compararlos lo que hace es devolver el resultado de calcular objeto1.Equals(objeto2) comprobando antes si alguno de los objetos vale null (sólo se devolvería true sólo si el otro también lo es)

 

Obviamente si se da una redefinición al Equals() no estático, esta también se aplicará al estático.

 

·        public static bool ReferenceEquals(object objeto1, object objeto2) à Indica si los dos objetos que se le pasan como parámetro se almacenan en la misma posición de memoria dinámica. A través de este método, aunque se hayan redefinido Equals() y el operador de igualdad (==) para un cierto tipo por referencia, se podrán seguir realizando comparaciones por referencia.entre objetos de ese tipo en tanto que redefinir de Equals() no afecta a este método. Por  ejemplo, dada la anterior redefinición de Equals() para objetos Persona:

 

Persona p = new Persona(“José”, 22, “83721654-W”);

Persona q = new Persona(“Antonio”, 23, “83721654-W”);

Console.WriteLine(p.Equals(q));

Console.WriteLine(Object.Equals(p, q));

Console.WriteLine(Object.ReferenceEquals(p, q));

Console.WriteLine(p == q);

 

La salida que por pantalla mostrará el código anterior es:

 

      True

            True

      False

            False

 

En los primeros casos se devuelve true porque según la redefinición de Equals() dos personas son iguales si tienen el mismo DNI, como pasa con los objetos p y q. Sin embargo, en los últimos casos se devuelve false porque aunque ambos objetos tienen el mismo DNI cada uno se almacena en la memoria dinámica en una posición distinta, que es lo que comparan ReferenceEquals() y  el operador == (éste último sólo por defecto)

 

 

 

Principal
Recomendado