Exportar (0) Imprimir
Expandir todo
Este artículo proviene de un motor de traducción automática. Mueva el puntero sobre las frases del artículo para ver el texto original. Más información.
Traducción
Original

Object.Equals (Método) (Object)

Determina si el objeto especificado es igual al objeto actual.

Espacio de nombres:  System
Ensamblado:  mscorlib (en mscorlib.dll)

public virtual bool Equals(
	Object obj
)

Parámetros

obj
Tipo: System.Object
Objeto que se va a comparar con el objeto actual.

Valor devuelto

Tipo: System.Boolean
true si el objeto especificado es igual al objeto actual; de lo contrario, false.

El tipo de comparación entre la instancia actual y el parámetro de obj depende de si la instancia actual es un tipo de referencia o un tipo de valor.

  • Si la instancia actual es un tipo de referencia, el método de Equals(Object) prueba de igualdad de referencia, y una llamada al método de Equals(Object) equivale a una llamada al método de ReferenceEquals . La igualdad de referencias significa que las variables de objeto se comparan que hacen referencia al mismo objeto. El ejemplo siguiente se muestra el resultado de la comparación. Define una clase de Person , que es un tipo de referencia, y llama al constructor de clase de Person para crear instancias de dos objetos nuevos, person1a y person2de Person , que tienen el mismo valor. También asigna person1a a otra variable de objeto, person1b. Como muestra el resultado del ejemplo, person1a y person1b son iguales porque hacen referencia al mismo objeto. Sin embargo, person1a y person2 no son iguales, aunque tienen el mismo valor.

    
    using System;
    
    // Define a reference type that does not override Equals.
    public class Person
    {
       private string personName;
    
       public Person(string name)
       {
          this.personName = name;
       }
    
       public override string ToString()
       {
          return this.personName;
       }
    }
    
    public class Example
    {
       public static void Main()
       {
          Person person1a = new Person("John");
          Person person1b = person1a;
          Person person2 = new Person(person1a.ToString());
    
          Console.WriteLine("Calling Equals:"); 
          Console.WriteLine("person1a and person1b: {0}", person1a.Equals(person1b));               
          Console.WriteLine("person1a and person2: {0}", person1a.Equals(person2));  
    
          Console.WriteLine("\nCasting to an Object and calling Equals:");
          Console.WriteLine("person1a and person1b: {0}", ((object) person1a).Equals((object) person1b));
          Console.WriteLine("person1a and person2: {0}", ((object) person1a).Equals((object) person2)); 
       }
    }
    // The example displays the following output:
    //       person1a and person1b: True
    //       person1a and person2: False
    //       
    //       Casting to an Object and calling Equals:
    //       person1a and person1b: True
    //       person1a and person2: False
    
    
    
  • Si la instancia actual es un tipo de valor, el método de Equals(Object) pruebas de igualdad de valores. La igualdad de valores significa lo siguiente:

    • Los dos objetos son del mismo tipo. Como se muestra en el ejemplo siguiente, un objeto de Byte que tiene un valor de 12 no es un objeto de Int32 que tiene un valor de 12, porque los dos objetos tienen distintos tipos en tiempo de ejecución.

      
      using System;
      
      public class Example
      {
         public static void Main()
         {
            byte value1 = 12;
            int value2 = 12;
      
            object object1 = value1;
            object object2 = value2;
      
            Console.WriteLine("{0} ({1}) = {2} ({3}): {4}",
                              object1, object1.GetType().Name,
                              object2, object2.GetType().Name,
                              object1.Equals(object2));
         }
      }
      // The example displays the following output:
      //        12 (Byte) = 12 (Int32): False
      
      
      
    • Los valores de los campos públicos y privados de los dos objetos son iguales. Las pruebas siguientes de ejemplo para la igualdad de valores. Define una estructura de Person , que es un tipo de valor, y llama al constructor de clase de Person para crear instancias de dos objetos nuevos, person1 y person2de Person , que tienen el mismo valor. Como el resultado del ejemplo, aunque las dos variables de objeto hacen referencia a distintos objetos, person1 y person2 son iguales porque tienen el mismo valor para el campo privado de personName .

      
      using System;
      
      // Define a value type that does not override Equals.
      public struct Person
      {
         private string personName;
      
         public Person(string name)
         {
            this.personName = name;
         }
      
         public override string ToString()
         {
            return this.personName;
         }
      }
      
      public struct Example
      {
         public static void Main()
         {
            Person person1 = new Person("John");
            Person person2 = new Person("John");
      
            Console.WriteLine("Calling Equals:"); 
            Console.WriteLine(person1.Equals(person2)); 
      
            Console.WriteLine("\nCasting to an Object and calling Equals:");
            Console.WriteLine(((object) person1).Equals((object) person2));  
         }
      }
      // The example displays the following output:
      //       Calling Equals:
      //       True
      //       
      //       Casting to an Object and calling Equals:
      //       True
      
      
      

Dado que la clase de Object es la clase base para todos los tipos de .NET Framework, el método de Object.Equals(Object) proporciona la comparación predeterminada de igualdad para todos los demás tipos. Sin embargo, los tipos reemplazan a menudo el método de Equals para implementar la igualdad de valores. Para obtener más información, vea las notas de los llamadores y notas para las secciones de los herederos.

Notas para Windows en tiempo de ejecución

Cuando se llama a la sobrecarga del método de Equals(Object) en una clase de Windows en tiempo de ejecución, proporciona el comportamiento predeterminado para las clases que no reemplazan Equals(Object). Esto forma parte de la compatibilidad que .NET Framework proporciona para Windows en tiempo de ejecución (vea Compatibilidad de .NET Framework con las aplicaciones de la Tienda Windows y Windows en tiempo de ejecución). Las clases de Windows en tiempo de ejecución no heredan Object, y no implementan actualmente un método de Equals(Object) . Sin embargo, aparecen para tener ToString, Equals(Object), y métodos de GetHashCode cuando se utiliza en código de C# o Visual Basic, y .NET Framework proporciona el comportamiento predeterminado para estos métodos.

NotaNota

las clases deWindows en tiempo de ejecución programadas en C# o Visual Basic pueden invalidar la sobrecarga del método de Equals(Object) .

Notas para los llamadores

Las clases derivadas con frecuencia reemplazan el método de Object.Equals(Object) para implementar la igualdad de valores. Además, los tipos también con frecuencia proporcionan una sobrecarga fuertemente tipada adicional al método de Equals , normalmente implementando la interfaz de IEquatable<T> . Cuando se llama al método de Equals para comprobar la igualdad, debe conocer si la instancia actual invalida Object.Equals y entender cómo una llamada concreta a un método de Equals se resuelve. De otro modo, podría hacer una prueba de igualdad diferente de la que pretendía, y el método devolvería un valor distinto al esperado.

Esto se muestra en el ejemplo siguiente. Crea una instancia de tres objetos de StringBuilder con cadenas idénticas y, a continuación cuatro llamadas a métodos de Equals .

La primera llamada al metodo devuelve true, y las tres siguientes devuelven false.


using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      StringBuilder sb1 = new StringBuilder("building a string...");
      StringBuilder sb2 = new StringBuilder("building a string...");

      Console.WriteLine("sb1.Equals(sb2): {0}", sb1.Equals(sb2));
      Console.WriteLine("((Object) sb1).Equals(sb2): {0}", 
                        ((Object) sb1).Equals(sb2));
      Console.WriteLine("Object.Equals(sb1, sb2): {0}",
                        Object.Equals(sb1, sb2));      

      Object sb3 = new StringBuilder("building a string...");
      Console.WriteLine("\nsb3.Equals(sb2): {0}", sb3.Equals(sb2));                              
   }
}
// The example displays the following output:
//       sb1.Equals(sb2): True
//       ((Object) sb1).Equals(sb2): False
//       Object.Equals(sb1, sb2): False
//
//       sb3.Equals(sb2): False


En el primer caso, se llama a la sobrecarga fuertemente tipada del método de StringBuilder.Equals(StringBuilder) , para comprobar la igualdad de valores. Dado que las cadenas asignadas a los dos objetos de StringBuilder son iguales, el método devuelve true. Sin embargo, StringBuilder no reemplaza Object.Equals(Object). Por ello, cuando el objeto de StringBuilder se convierte a Object, cuando una instancia de StringBuilder se asigna a una variable de Objectescrito y, cuando el método de Object.Equals(Object, Object) se pasa dos objetos de StringBuilder , el método de Object.Equals(Object) predeterminado se denomina. Dado que StringBuilder es un tipo de referencia, es equivalente a pasar los dos objetos de StringBuilder al método de ReferenceEquals . Aunque los tres objetos de StringBuilder contienen cadenas idénticas, hacen referencia a tres objetos distintos. Como resultado, estas tres llamadas a métodos devuelven false.

Puede comparar el objeto actual con otro objeto para la igualdad de la referencia llamando al método ReferenceEquals. En Visual Basic, puede utilizar la palabra clave (por ejemplo, If Me Is otherObject Then ...) is también.

Notas a herederos.

Cuando se define el propio tipo, ese tipo hereda la funcionalidad definida por el método de Equals de su tipo base. La tabla siguiente muestra la implementación predeterminada del método de Equals para las categorías principales de tipos de .NET Framework.

Categoría de tipo

Igualdad definida por

Comentarios

Clase derivada directamente de Object

Object.Equals(Object)

Igualdad de referencia; equivalente a Object.ReferenceEquals.

Estructura

ValueType.Equals

Igualdad de valor; comparación directa de byte-por- byte o comparación de campo-por- campo mediante la reflexión.

Enumeración

Enum.Equals

Los valores deben tener el mismo tipo de enumeración y el mismo valor subyacente.

delegate

MulticastDelegate.Equals

Los delegados deben tener el mismo tipo con listas de invocación idénticas.

interface

Object.Equals(Object)

Igualdad de referencia.

Para un tipo de valor, debe invalidar siempre Equals, porque las pruebas de igualdad que dependen de un rendimiento de la propuesta de reflexión. También puede invalidar la implementación predeterminada de Equals para que los tipos de referencia comprueben la igualdad de valores en lugar de igualdad de referencia y definen el significado exacto de igualdad de valores. Tales implementaciones de retorno true de Equals si los dos objetos tienen el mismo valor, aunque no son la misma instancia. El implementador de tipo decide qué constituye el valor de un objeto, pero suele ser varios o todos los datos almacenados en las variables de instancia del objeto. Por ejemplo, el valor de un objeto de String se basa en los caracteres de la cadena; el método de String.Equals(Object) invalida el método de Object.Equals(Object) para devolver true para cualquier dos instancias de la cadena que contiene los mismos caracteres en el mismo orden.

El ejemplo siguiente muestra cómo invalidar el método de Object.Equals(Object) para comprobar la igualdad de valores. Invalida el método de Equals para la clase de Person . Si Person aceptara la implementación de la clase base de igualdad, dos objetos de Person se iguales sólo si se hizo referencia a un único objeto. Sin embargo, en este caso, dos objetos de Person son iguales si tienen el mismo valor para la propiedad de Person.Id .


public class Person
{
   private string idNumber;
   private string personName;

   public Person(string name, string id)
   {
      this.personName = name;
      this.idNumber = id;
   }

   public override bool Equals(Object obj)
   {
      Person personObj = obj as Person; 
      if (personObj == null)
         return false;
      else
         return idNumber.Equals(personObj.idNumber);
   }

   public override int GetHashCode()
   {
      return this.idNumber.GetHashCode(); 
   }
}

public class Example
{
   public static void Main()
   {
      Person p1 = new Person("John", "63412895");
      Person p2 = new Person("Jack", "63412895");
      Console.WriteLine(p1.Equals(p2));
      Console.WriteLine(Object.Equals(p1, p2));
   }
}
// The example displays the following output:
//       True
//       True


Además de reemplazar Equals, puede implementar la interfaz de IEquatable<T> para proporcionar una prueba fuertemente tipada para la igualdad.

Las instrucciones siguientes deben ser true para todas las implementaciones del método Equals(Object). En la lista, x, y, y z representan las referencias a objetos que no son Null.

  • x.Equals(x) devuelve true, excepto en los casos que implican tipos de punto flotante. Vea el 60559:2011 de ISO/IEC/IEEE, TI -- Sistemas de microprocesador -- Aritmética flotante.

  • x.Equals(y) devuelve el mismo valor que y.Equals(x).

  • x.Equals(y) devuelve true si x y y son NaN.

  • Si (x.Equals(y) && y.Equals(z)) vuelve true, después x.Equals(z) vuelve true.

  • Las llamadas sucesivas a x.Equals(y) devuelven el mismo valor siempre que los objetos a los que hace referencia x y y no se modifiquen.

  • x.Equals(null) devuelve false.

Las implementaciones de Equals no deben producir excepciones; siempre deben devolver un valor. Por ejemplo, si obj es null, el método de Equals debe devolver false en lugar de producir ArgumentNullException.

Siga estas instrucciones al reemplazar Equals(Object):

  • Los tipos que implementan IComparable deben reemplazar el método Equals(Object).

  • Los tipos que reemplazan Equals(Object) también deben reemplazar GetHashCode; si no, las tablas hash podrían no funcionar correctamente.

  • Debería considerar implementar la interfaz de IEquatable<T> para admitir las pruebas fuertemente tipadas para la igualdad. La implementación de IEquatable<T>.Equals si devolver resultados coherentes con Equals.

  • Si el lenguaje de programación admite la sobrecarga de operadores y se sobrecarga el operador de igualdad para un tipo determinado, también debe reemplazar el método de Equals(Object) devuelva el mismo resultado que el operador de igualdad. Esto ayuda a garantizar que el código de biblioteca de clases que utilice Equals (como ArrayList y Hashtable) se comporta de forma coherente con la manera en que el código de aplicación usa el operador de igualdad.

bsc2ak47.collapse_all(es-es,VS.110).gifInstrucciones para los tipos de referencia

Las instrucciones siguientes se aplican a reemplazar Equals(Object) un tipo de referencia:

  • Considere reemplazar Equals si la semántica de tipos se basa en el hecho de que el tipo representa algunos valores.

  • La mayoría de los tipos de referencia no deben sobrecargar el operador de igualdad, aunque reemplacen el método Equals. No obstante, cuando se implemente un tipo de referencia destinado a tener semántica de valor, como un tipo de número complejo, debe reemplazarse el operador de igualdad.

  • No debe reemplazar Equals en un tipo de referencia mutable. Esto se debe reemplazar Equals requiere que también invalida el método de GetHashCode , como se describe en la sección anterior. Esto significa que el código hash de una instancia de un tipo de referencia mutable puede cambiar durante su duración, que puede producir el objeto se pierdan en una tabla hash.

bsc2ak47.collapse_all(es-es,VS.110).gifInstrucciones para los tipos de valor

Las instrucciones siguientes se aplican a reemplazar Equals(Object) un tipo de valor:

  • Si define un tipo de valor que incluya uno o más campos cuyos valores son tipos de referencia, debe invalidar Equals(Object). La implementación de Equals(Object) proporcionada por ValueType realiza una comparación de byte-por- bytes para los tipos de valor cuyos campos son todos los tipos de valor, pero utiliza la reflexión para realizar una comparación de campo-por- campo de los tipos de valor cuyos campos incluyen los tipos de referencia.

  • Si reemplaza Equals y el lenguaje de desarrollo admite la sobrecarga de operadores, debe sobrecargar el operador de igualdad.

  • Debe implementar la interfaz de IEquatable<T> . Llamar al método fuertemente tipado de IEquatable<T>.Equals evita la grafía el argumento de obj .

El ejemplo siguiente se muestra una clase de Point que invalide el método de Equals para proporcionar igualdad de valor, y una clase de Point3D que se deriva de Point. Dado que Point reemplaza Object.Equals(Object) para comprobar la igualdad de valor, el método de Object.Equals(Object) no se denomina. Sin embargo, Point3D.Equals llama Point.Equals porque Point implementa Object.Equals(Object) de una forma que proporciona la igualdad de valores.


using System;

class Point
{
   protected int x, y;

   public Point() : this(0, 0) 
   { }

   public Point(int x, int y) 
   {
      this.x = x;
      this.y = y;
   }

   public override bool Equals(Object obj) 
   {
      //Check for null and compare run-time types.
      if ((obj == null) || ! this.GetType().Equals(obj.GetType())) {
         return false;
      }
      else { 
         Point p = (Point) obj; 
         return (x == p.x) && (y == p.y);
      }   
   }

   public override int GetHashCode() 
   {
      return (x << 2) ^ y;
   }

    public override string ToString()
    {
        return String.Format("Point({0}, {1})", x, y);
    }
}

sealed class Point3D: Point 
{
   int z;

   public Point3D(int x, int y, int z) : base(x, y) 
   {
      this.z = z; 
   }

   public override bool Equals(Object obj) 
   {
      Point3D pt3 = obj as Point3D;
      if (pt3 == null)
         return false;
      else
         return base.Equals((Point)obj) && z == pt3.z;
   }

   public override int GetHashCode() 
   {
      return (base.GetHashCode() << 2) ^ z;
   }

   public override String ToString() 
   {
        return String.Format("Point({0}, {1}, {2})", x, y, z);
    }
}

class Example 
{
  public static void Main() 
  {
     Point point2D = new Point(5, 5);
     Point3D point3Da = new Point3D(5, 5, 2);
     Point3D point3Db = new Point3D(5, 5, 2);
     Point3D point3Dc = new Point3D(5, 5, -1);

     Console.WriteLine("{0} = {1}: {2}", 
                       point2D, point3Da, point2D.Equals(point3Da));
     Console.WriteLine("{0} = {1}: {2}", 
                       point2D, point3Db, point2D.Equals(point3Db));        
     Console.WriteLine("{0} = {1}: {2}", 
                       point3Da, point3Db, point3Da.Equals(point3Db));
     Console.WriteLine("{0} = {1}: {2}", 
                       point3Da, point3Dc, point3Da.Equals(point3Dc));
  } 
}
// The example displays the following output:
//       Point(5, 5) = Point(5, 5, 2): False
//       Point(5, 5) = Point(5, 5, 2): False
//       Point(5, 5, 2) = Point(5, 5, 2): True
//       Point(5, 5, 2) = Point(5, 5, -1): False


Comprueba si el método de Point.Equals para asegurarse de que el argumento de obj no es Null y que haga referencia a una instancia del mismo tipo que este objeto. Si cualquiera de los errores activados, el método devuelve false.

Las llamadas al método de Point.Equals el método de GetType para determinar si los tipos en tiempo de ejecución de los dos objetos son idénticos. Si el método utilizado una comprobación del formulario obj is Point en C# o de TryCast(obj, Point) en Visual Basic, la comprobación devolvería true en caso de que obj es una instancia de una clase derivada de Point, aunque obj y la instancia actual no son del mismo tipo en tiempo de ejecución. Comprueba que los dos objetos son del mismo tipo, el método convierte obj para escribir Point y devuelve el resultado de comparar los campos de instancia de los dos objetos.

En Point3D.Equals, se invoca el método heredado de Point.Equals , que reemplaza Object.Equals(Object), antes de que se haga nada más. Dado que Point3D es una clase sealed (NotInheritable en Visual Basic), un escribir el formulario obj is Point en C# o TryCast(obj, Point) en Visual Basic es necesario asegurarse de que obj es un objeto de Point3D . Si es un objeto de Point3D , se convierte a un objeto de Point y se pasa a la implementación de la clase base de Equals. Cuando el método heredado de Point.Equals vuelve true hace que el método compara los campos de instancia de z proporcionados en la clase derivada.

El ejemplo siguiente se define una clase de Rectangle que internamente implemente un rectángulo como dos objetos de Point . La clase de Rectangle también invalida Object.Equals(Object) para ofrecer igualdad de valor.


using System;

class Rectangle 
{
   private Point a, b;

   public Rectangle(int upLeftX, int upLeftY, int downRightX, int downRightY) {
      this.a = new Point(upLeftX, upLeftY);
      this.b = new Point(downRightX, downRightY);
   }

   public override bool Equals(Object obj) {
      // Perform an equality check on two rectangles (Point object pairs).
      if (obj == null || GetType() != obj.GetType()) 
          return false;
      Rectangle r = (Rectangle)obj;
      return a.Equals(r.a) && b.Equals(r.b);
   }

   public override int GetHashCode() {
      return Tuple.Create(a, b).GetHashCode();
   }

    public override String ToString() 
    {
       return String.Format("Rectangle({0}, {1}, {2}, {3})",
                            a.x, a.y, b.x, b.y); 
    }
}

class Point 
{
  internal int x;
  internal int y;

  public Point(int X, int Y) {
     this.x = X;
     this.y = Y;
  }

  public override bool Equals (Object obj) {
     // Performs an equality check on two points (integer pairs).
     if (obj == null || GetType() != obj.GetType()) return false;
     Point p = (Point)obj;
     return (x == p.x) && (y == p.y);
  }

  public override int GetHashCode() {
     return Tuple.Create(x, y).GetHashCode();
  }
}

class Example 
{
   public static void Main() 
   {
      Rectangle r1 = new Rectangle(0, 0, 100, 200);
      Rectangle r2 = new Rectangle(0, 0, 100, 200);
      Rectangle r3 = new Rectangle(0, 0, 150, 200);

      Console.WriteLine("{0} = {1}: {2}", r1, r2, r1.Equals(r2));
      Console.WriteLine("{0} = {1}: {2}", r1, r3, r1.Equals(r3));
      Console.WriteLine("{0} = {1}: {2}", r2, r3, r2.Equals(r3));
   }
}
// The example displays the following output:
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 100, 200): True
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False
//    Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False


Algunos lenguajes como sobrecarga de operadores admiten de C# y Visual Basic. Cuando un tipo sobrecarga el operador de igualdad, también debe reemplazar el método Equals(Object) para ofrecer la misma funcionalidad. Esto se consigue normalmente escribiendo el método Equals(Object) en términos del operador de igualdad sobrecargado, como en el siguiente ejemplo de código.


using System;

public struct Complex {
   public double re, im;

   public override bool Equals(Object obj) {
      return obj is Complex && this == (Complex)obj;
   }

   public override int GetHashCode() {
      return Tuple.Create(re, im).GetHashCode();
   }

   public static bool operator ==(Complex x, Complex y) {
      return x.re == y.re && x.im == y.im;
   }

   public static bool operator !=(Complex x, Complex y) {
      return !(x == y);
   }

    public override String ToString()
    {
       return String.Format("({0}, {1})", re, im);
    } 
}

class MyClass 
{
  public static void Main() 
  {
    Complex cmplx1, cmplx2;

    cmplx1.re = 4.0;
    cmplx1.im = 1.0;

    cmplx2.re = 2.0;
    cmplx2.im = 1.0;

    Console.WriteLine("{0} <> {1}: {2}", cmplx1, cmplx2, cmplx1 != cmplx2);        
    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2));        

    cmplx2.re = 4.0;

    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1 == cmplx2);        
    Console.WriteLine("{0} = {1}: {2}", cmplx1, cmplx2, cmplx1.Equals(cmplx2));          
  }
}
// The example displays the following output:
//       (4, 1) <> (2, 1): True
//       (4, 1) = (2, 1): False
//       (4, 1) = (4, 1): True
//       (4, 1) = (4, 1): True


Dado que Complex es un tipo de valor, no puede derivarse de. Por consiguiente, la invalidación del método de Equals(Object) no necesita llamar a GetType para determinar el tipo exacto del runtime de cada objeto, pero puede usar el operador de is en C# o el operador de TypeOf en Visual Basic para comprobar el tipo de parámetro de obj .

.NET Framework

Compatible con: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Compatible con: 4, 3.5 SP1

Biblioteca de clases portable

Compatible con: Biblioteca de clases portable

.NET para aplicaciones de la Tienda Windows

Compatible con: Windows 8

.NET para aplicaciones de Windows Phone

Compatible con: Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (no se admite el rol Server Core), Windows Server 2008 R2 (se admite el rol Server Core con SP1 o versiones posteriores; no se admite Itanium)

.NET Framework no admite todas las versiones de todas las plataformas. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

Adiciones de comunidad

AGREGAR
Mostrar:
© 2014 Microsoft