Tipo de valor C # y aprendizaje de tipo de referencia

Directorio

1. Introducción

2. Concepto

Tipo de valor

Tipo de referencia

exploración de cuerdas

3. Tipo de sistema común (CTS)

4. El despliegue de tipos de valor y tipos de referencia en la memoria.

Comprensión de pilas y montones

Pila

Montón

Asignación de tipos de valor y tipos de referencia en la pila y el montón

5. Tipo de valor y tipo de referencia ocasiones aplicables

Referencia


1. Introducción

He estado aprendiendo C # durante casi dos años. No he estado en C y C ++ antes, pero no sé lo básico, por lo que no pasé demasiado tiempo en lo básico al estudiar en C #. Luego encontré problemas con el proyecto. Voy a encontrar un trabajo, creo que todavía tengo que aprender los conceptos básicos. Hoy, echemos un vistazo a la diferencia entre los tipos de valores de C # y los tipos de referencia.

2. Concepto

Hay dos tipos básicos en c #, son el tipo de valor y el tipo de referencia

Tipo de valor

Las variables se almacenan directamente en la memoria, y byte, short, int, long, float, double, decimal, char, bool y struct se denominan colectivamente tipos de valor. Todos los tipos de valor están sellados implícitamente (no se pueden derivar nuevos tipos de valor), el propósito es evitar que otros tipos se deriven de los tipos de valor. Después de declarar la variable de tipo de valor, el compilador le asigna memoria, ya sea que se haya asignado o no.

Todos los tipos de valores de C # se derivan implícitamente de System.ValueType:

Estructura: struct (derivada directamente de System.ValueType);
tipo de valor:

  • : : Sbyte (System.SByte 的 别名) , short (System.Int16) , int (System.Int32) , long (System.Int64) , byte (System.Byte) , ushort (System.UInt16) , uint (System .UInt32) , ulong (System.UInt64) , char (System.Char) ;
  • 浮点 型 : flotante (System.Single) , double (System.Double) ;
  • decimal (System.Decimal), utilizado para alta precisión en los cálculos financieros.
  • tipo bool: bool (alias para System.Boolean);
  • struct (derivado de System.ValueType).
  • enum (derivado de System.Enum);
  • Tipo anulable (derivado de la estructura genérica System.Nullable <T>, T? Es en realidad un alias de System.Nullable <T>).

Vale la pena señalar que tanto los tipos de referencia como los tipos de valor heredan de la clase System.Object. La diferencia es que casi todos los tipos de referencia heredan directamente de System.Object, mientras que los tipos de valor heredan sus subclases, es decir, heredan directamente System.ValueType. System.ValueType se deriva directamente de System.Object. Es decir, System.ValueType en sí mismo es un tipo de clase, no un tipo de valor. La clave es que ValueType reescribe el método Equals (), de modo que el tipo de valor se compara de acuerdo con el valor de la instancia, no con la dirección de referencia.

Puede usar la propiedad Type.IsValueType para determinar si un tipo es un tipo de valor:

TestType testType = new TestType ();
if (testTypetype.GetType().IsValueType)
{
     Console.WriteLine("{0} is value type.", testType.ToString());
}

Tipo de referencia

Las variables de tipo de referencia contienen referencias a datos. Los datos se almacenan en el montón de datos. La cadena y la clase se denominan colectivamente tipos de referencia. Al declarar una clase, solo se asigna un pequeño trozo de memoria en la pila para contener una dirección, y en este momento no se le asigna espacio de memoria en el montón . Cuando use new para crear una instancia de una clase, asigne espacio en el montón y guarde la dirección del espacio en el montón en el pequeño espacio asignado en la pila.

C # tiene los siguientes tipos de referencia:

  • Array (derivado de System.Array)
  • El usuario define los siguientes tipos:
  • Clase: clase (derivada de System.Object);
  • Interfaz: interfaz (la interfaz no es un "algo", por lo que no se trata de dónde se deriva. Anders dijo en "Lenguaje de programación C #", la interfaz es solo una convención [contrato]);
  • Delegado: delegado (derivado de System.Delegate).
  • objeto (alias de System.Object);
  • Cadena: cadena (alias de System.String).

exploración de cuerdas

Obviamente, las asignaciones de cadenas son todos los tipos de valor, ¿qué pasa con los tipos de referencia?

La programación de .net framework (edición revisada) tiene esta descripción:

El tipo de cadena hereda directamente Object, lo que lo convierte en un tipo de referencia, lo que significa que ninguna cadena residirá en la pila del hilo.

El nombre

Tipo CTS

Explicación

cuerda

System.String

Cadena Unicode

string s1 = "aaaa";
 
string s2 = s1;
 
Console.WriteLine("s1:" + s1);
 
Console.WriteLine("s2:" + s2);
 
s1 = "bbbb";
 
Console.WriteLine("s1:" + s1);
 
Console.WriteLine("s2:" + s2);
 
Console.ReadKey();

En la cadena, la dirección S1 inicialmente apunta a aaaa. Como S2 = S1, la dirección S2 también apunta a aaaa. Como se muestra

Cuando bbbb se asigna nuevamente a S1, los datos bbbb se abrirán en el montón y los datos aaaa no han desaparecido y no se han sobrescrito. La dirección S1 apuntará a bbbb en el montón

La dirección S2 todavía apunta a aaaa. Como se muestra

El código anterior asigna tipos de valor, pero la cadena es un tipo de referencia. La cadena se asigna en el montón, no en la pila. Por lo tanto, cuando asigna una variable de cadena a otra cadena, obtendrá dos referencias a la misma cadena en la memoria. Sin embargo, los tipos de cadena y referencia tienen algunas diferencias en las operaciones comunes. Por ejemplo, la cadena es inmutable. La modificación de una de las cadenas creará un nuevo objeto de cadena, mientras que la otra cadena no cambiará.

3. Tipo de sistema común (CTS)

Los tipos de datos básicos de C # se definen de manera independiente de la plataforma. Los tipos predefinidos de C # no están integrados en el lenguaje, sino en .NET Framework. Todos los lenguajes orientados a .NET finalmente se compilan en IL.

Por ejemplo, cuando una variable int se declara en C #, en realidad es una instancia de System.Int32 en CTS. Esto tiene implicaciones importantes:
garantizar la seguridad de tipo obligatorio en IL;
lograr la interoperabilidad entre diferentes lenguajes .NET; y
todos los tipos de datos son objetos. Pueden tener métodos, propiedades, etc. Por ejemplo: ToString ().

4. El despliegue de tipos de valor y tipos de referencia en la memoria.

Comprensión de pilas y montones

Pila

La pila solo puede operar en datos en un extremo, es decir, en la parte superior de la pila. '

La pila también es una estructura de memoria de autogestión: empujar la pila automáticamente asigna memoria y al abrirla se borra automáticamente la memoria ocupada.

  Otros dos puntos a destacar:

     1. La memoria en la pila no se puede solicitar dinámicamente, y la memoria solo se puede asignar para datos de cierto tamaño. La flexibilidad no es alta, pero la eficiencia de ejecución de la pila es muy alta .

     2. El espacio disponible en la pila no es grande, por lo que debemos prestar atención al impacto del tamaño de los datos al operar los datos asignados a la pila.

Montón

   El montón es diferente de la pila. El montón se usa para almacenar objetos de instancia reales en C #, que pueden almacenar una gran cantidad de datos, y el montón puede asignar dinámicamente espacio de almacenamiento .

   En comparación con la pila solo se puede operar en un extremo, se puede acceder a los datos en el montón a voluntad .

   Sin embargo, la estructura del montón hace que la eficiencia de ejecución del montón no sea tan alta como la pila, y no puede reciclar automáticamente los objetos usados. Para la recuperación de memoria en el montón, los programadores de C ++ necesitan realizar una recuperación manual, lo que también vale la pena señalar en la programación de C ++, de lo contrario, es fácil causar un desbordamiento de memoria. Para los programadores .NET, la plataforma proporciona un mecanismo de recolección de basura (GC) que puede recolectar automáticamente objetos caducados en el montón.

Asignación de tipos de valor y tipos de referencia en la pila y el montón

Aquí hay dos principios:

    (1) Al crear un tipo de referencia, el tiempo de ejecución asignará dos espacios para él: un espacio se asigna en el montón para almacenar los datos del tipo de referencia en sí, y el otro espacio de bloque se asigna en la pila para almacenar la referencia a los datos en el montón (en realidad La dirección de memoria en el almacenamiento dinámico almacenado, es decir, el puntero).

    (2) Al crear un tipo de valor, el tiempo de ejecución asignará un espacio para este, este espacio se asigna donde se crea la variable , como:

      Si el tipo de valor se crea dentro del método, el método se inserta en la pila y se asigna a la pila para su almacenamiento.

      Si el tipo de valor es una variable miembro de un tipo de referencia, sigue el tipo de referencia y se almacena en el montón.

Referencia de introducción más detallada: https://blog.csdn.net/qiaoquan3/article/details/51202926

5. Tipo de valor y tipo de referencia ocasiones aplicables

Los tipos de valor tienen una mejor eficiencia en la gestión de la memoria y no admiten el polimorfismo, adecuado para su uso como soporte para almacenar datos; los tipos de referencia admiten el polimorfismo, adecuado para definir el comportamiento de la aplicación.

En C #, usamos struct / class para declarar un tipo como un tipo de valor / tipo de referencia. Considere el siguiente ejemplo:
SomeType [] oneTypes = new SomeType [100];
Si SomeType es un tipo de valor, solo necesita asignarlo una vez, y el tamaño es 100 veces el tamaño de SomeType. Si SomeType es un tipo de referencia, debe asignarse 100 veces al principio. Después de la asignación, cada valor de elemento de la matriz es nulo y luego se inicializan 100 elementos, lo que da como resultado un total de 101 asignaciones. Esto consumirá más tiempo y causará más fragmentación de memoria. Por lo tanto, si la responsabilidad del tipo es principalmente almacenar datos, el tipo de valor es más apropiado.
En general, el tipo de valor (no admite polimorfismo) es adecuado para almacenar datos para operaciones de aplicación C #, y el tipo de referencia (admite polimorfismo) debe usarse para definir el comportamiento de la aplicación. Por lo general, creamos más tipos de referencia que tipos de valor. Si se cumplen las siguientes condiciones, deberíamos crear un tipo de valor:
la responsabilidad principal de este tipo se utiliza para el almacenamiento de datos. 
La interfaz común de este tipo está completamente definida por algunos atributos de acceso de miembros de datos. 
Este tipo nunca puede tener subclases. 
Este tipo no tiene comportamiento polimórfico.
 

Referencia

Tipos de referencia y tipos de valor en C #

Tipos de valor y tipos de referencia en C #

¿Es el tipo de cadena un tipo de valor o un tipo de referencia en C #?

C # explica la diferencia entre los tipos de valor y los tipos de referencia

30 artículos originales publicados · Me gusta1 · Visitas1158

Supongo que te gusta

Origin blog.csdn.net/chunchunlaila/article/details/105472903
Recomendado
Clasificación