Objetos (Guía de programación de C#)Objects (C# Programming Guide)

Una definición de clase o estructura es como un plano que especifica qué puede hacer el tipo.A class or struct definition is like a blueprint that specifies what the type can do. Un objeto es básicamente un bloque de memoria que se ha asignado y configurado de acuerdo con el plano.An object is basically a block of memory that has been allocated and configured according to the blueprint. Un programa puede crear muchos objetos de la misma clase.A program may create many objects of the same class. Los objetos también se denominan instancias y pueden almacenarse en una variable con nombre, o en una matriz o colección.Objects are also called instances, and they can be stored in either a named variable or in an array or collection. El código de cliente es el código que usa estas variables para llamar a los métodos y acceder a las propiedades públicas del objeto.Client code is the code that uses these variables to call the methods and access the public properties of the object. En un lenguaje orientado a objetos, como C#, un programa típico consta de varios objetos que interactúan dinámicamente.In an object-oriented language such as C#, a typical program consists of multiple objects interacting dynamically.

Nota

Los tipos estáticos se comportan de forma diferente a lo que se describe aquí.Static types behave differently than what is described here. Para más información, vea Clases estáticas y sus miembros.For more information, see Static Classes and Static Class Members.

Instancias de estructura frente a Instancias de claseStruct Instances vs. Class Instances

Puesto que las clases son tipos de referencia, una variable de un objeto de clase contiene una referencia a la dirección del objeto del montón administrado.Because classes are reference types, a variable of a class object holds a reference to the address of the object on the managed heap. Si se asigna un segundo objeto del mismo tipo al primer objeto, ambas variables hacen referencia al objeto de esa dirección.If a second object of the same type is assigned to the first object, then both variables refer to the object at that address. Este punto se analiza con más detalle más adelante en este tema.This point is discussed in more detail later in this topic.

Las instancias de clases se crean mediante el operador new.Instances of classes are created by using the new operator. En el ejemplo siguiente, Person es el tipo, y person1 y person 2 son instancias u objetos de ese tipo.In the following example, Person is the type and person1 and person 2 are instances, or objects, of that type.

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    // Other properties, methods, events...
}

class Program
{
    static void Main()
    {
        Person person1 = new Person("Leopold", 6);
        Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);

        // Declare new person, assign person1 to it.
        Person person2 = person1;

        // Change the name of person2, and person1 also changes.
        person2.Name = "Molly";
        person2.Age = 16;

        Console.WriteLine("person2 Name = {0} Age = {1}", person2.Name, person2.Age);
        Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();

    }
}
/*
    Output:
    person1 Name = Leopold Age = 6
    person2 Name = Molly Age = 16
    person1 Name = Molly Age = 16
*/

Dado que las estructuras son tipos de valor, una variable de un objeto de estructura contiene una copia de todo el objeto.Because structs are value types, a variable of a struct object holds a copy of the entire object. También se pueden crear instancias de estructuras usando el operador new, pero esto no resulta necesario, como se muestra en el ejemplo siguiente:Instances of structs can also be created by using the new operator, but this is not required, as shown in the following example:

public struct Person
{
    public string Name;
    public int Age;
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

public class Application
{
    static void Main()
    {
        // Create  struct instance and initialize by using "new".
        // Memory is allocated on thread stack.
        Person p1 = new Person("Alex", 9);
        Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);

        // Create  new struct object. Note that  struct can be initialized
        // without using "new".
        Person p2 = p1;

        // Assign values to p2 members.
        p2.Name = "Spencer";
        p2.Age = 7;
        Console.WriteLine("p2 Name = {0} Age = {1}", p2.Name, p2.Age);

        // p1 values remain unchanged because p2 is  copy.
        Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/*
  Output:
    p1 Name = Alex Age = 9
    p2 Name = Spencer Age = 7
    p1 Name = Alex Age = 9
*/

La memoria para p1 y p2 se asigna en la pila de subprocesos.The memory for both p1 and p2 is allocated on the thread stack. Esta memoria se reclama junto con el tipo o método en el que se declara.That memory is reclaimed along with the type or method in which it is declared. Este es uno de los motivos por los que se copian las estructuras en la asignación.This is one reason why structs are copied on assignment. Por el contrario, la memoria que se asigna a una instancia de clase la reclama automáticamente (recolección de elementos no utilizados) Common Language Runtime cuando todas las referencias al objeto se han salido del ámbito.By contrast, the memory that is allocated for a class instance is automatically reclaimed (garbage collected) by the common language runtime when all references to the object have gone out of scope. No es posible destruir de forma determinante un objeto de clase como en C++.It is not possible to deterministically destroy a class object like you can in C++. Para obtener más información sobre la recolección de elementos no utilizados en .NET Framework, consulte Recolección de elementos no utilizados.For more information about garbage collection in the .NET Framework, see Garbage Collection.

Nota

La asignación y desasignación de memoria en el montón administrado están muy optimizadas en Common Language Runtime.The allocation and deallocation of memory on the managed heap is highly optimized in the common language runtime. En la mayoría de los casos, no existe ninguna diferencia significativa en el costo de rendimiento entre asignar una instancia de clase en el montón y asignar una instancia de estructura en la pila.In most cases there is no significant difference in the performance cost of allocating a class instance on the heap versus allocating a struct instance on the stack.

Identidad de objeto frente a igualdad de valoresObject Identity vs. Value Equality

Cuando se comparan dos objetos para comprobar si son iguales, primero debe determinar si quiere saber si las dos variables representan el mismo objeto en la memoria o si los valores de uno o varios de sus campos son equivalentes.When you compare two objects for equality, you must first distinguish whether you want to know whether the two variables represent the same object in memory, or whether the values of one or more of their fields are equivalent. Si tiene previsto comparar valores, debe tener en cuenta si los objetos son instancias de tipos de valor (estructuras) o tipos de referencia (clases, delegados y matrices).If you are intending to compare values, you must consider whether the objects are instances of value types (structs) or reference types (classes, delegates, arrays).

  • Para determinar si dos instancias de clase hacen referencia a la misma ubicación en la memoria (lo que significa que tienen la misma identidad), use el método estático Equals.To determine whether two class instances refer to the same location in memory (which means that they have the same identity), use the static Equals method. (System.Object es la clase base implícita para todos los tipos de valor y tipos de referencia, incluidas las clases y estructuras definidas por el usuario).(System.Object is the implicit base class for all value types and reference types, including user-defined structs and classes.)

  • Para determinar si los campos de instancia de dos instancias de estructura presentan los mismos valores, use el método ValueType.Equals.To determine whether the instance fields in two struct instances have the same values, use the ValueType.Equals method. Dado que todas las estructuras heredan implícitamente de System.ValueType, se llama al método directamente en el objeto, como se muestra en el ejemplo siguiente:Because all structs implicitly inherit from System.ValueType, you call the method directly on your object as shown in the following example:

// Person is defined in the previous example.

//public struct Person
//{
//    public string Name;
//    public int Age;
//    public Person(string name, int age)
//    {
//        Name = name;
//        Age = age;
//    }
//}

Person p1 = new Person("Wallace", 75);
Person p2;
p2.Name = "Wallace";
p2.Age = 75;

if (p2.Equals(p1))
    Console.WriteLine("p2 and p1 have the same values.");

// Output: p2 and p1 have the same values.

La implementación System.ValueType de Equals usa la reflexión porque debe poder determinar cuáles son los campos en cualquier estructura.The System.ValueType implementation of Equals uses reflection because it must be able to determine what the fields are in any struct. Al crear sus propias estructuras, invalide el método Equals para proporcionar un algoritmo de igualdad eficaz específico de su tipo.When creating your own structs, override the Equals method to provide an efficient equality algorithm that is specific to your type.

  • Para determinar si los valores de los campos de dos instancias de clase son iguales, puede usar el método Equals o el operador ==.To determine whether the values of the fields in two class instances are equal, you might be able to use the Equals method or the == operator. En cambio, úselos solo si la clase los ha invalidado o sobrecargado para proporcionar una definición personalizada de lo que significa "igualdad" para los objetos de ese tipo.However, only use them if the class has overridden or overloaded them to provide a custom definition of what "equality" means for objects of that type. La clase también puede implementar la interfaz IEquatable<T> o la interfaz IEqualityComparer<T>.The class might also implement the IEquatable<T> interface or the IEqualityComparer<T> interface. Ambas interfaces proporcionan métodos que pueden servir para comprobar la igualdad de valores.Both interfaces provide methods that can be used to test value equality. Al diseñar sus propias clases que invaliden Equals, asegúrese de seguir las instrucciones descritas en Cómo: Definir la igualdad de valores para un tipo y Object.Equals(Object).When designing your own classes that override Equals, make sure to follow the guidelines stated in How to: Define Value Equality for a Type and Object.Equals(Object).

Para obtener más información:For more information:

Vea tambiénSee also