Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Cuando se compila un tipo o método genérico en lenguaje intermedio común (CIL), contiene metadatos que lo identifican como parámetros de tipo. La forma en que se usa la CIL para un tipo genérico difiere en función de si el parámetro de tipo proporcionado es un tipo de valor o un tipo de referencia.
Cuando un tipo genérico se construye por primera vez con un tipo de valor como parámetro, el tiempo de ejecución crea un tipo genérico especializado con el parámetro o parámetros proporcionados sustituidos en las ubicaciones adecuadas de la CIL. Los tipos genéricos especializados se crean una vez para cada tipo de valor único que se usa como parámetro.
Por ejemplo, supongamos que el código del programa declaró una pila construida con enteros:
Stack<int>? stack;
En este momento, el tiempo de ejecución genera una versión especializada de la Stack<T> clase que tiene el entero sustituido adecuadamente por su parámetro. Ahora, siempre que el código del programa use una pila de enteros, el tiempo de ejecución reutiliza la clase especializada Stack<T> generada. En el ejemplo siguiente, se crean dos instancias de una pila de enteros y comparten una sola instancia del Stack<int>
código:
Stack<int> stackOne = new Stack<int>();
Stack<int> stackTwo = new Stack<int>();
Sin embargo, supongamos que en otro punto del código se crea otra Stack<T> clase con un tipo de valor diferente, como una long
o una estructura definida por el usuario. Como resultado, el motor de ejecución genera otra versión del tipo genérico y sustituye un long
en los lugares apropiados en el CIL. Las conversiones ya no son necesarias porque cada clase genérica especializada contiene de forma nativa el tipo de valor.
Los genéricos funcionan de forma algo diferente para los tipos de referencia. La primera vez que se construye un tipo genérico con cualquier tipo de referencia, el tiempo de ejecución crea un tipo genérico especializado con referencias de objeto sustituidas por los parámetros de la CIL. A continuación, cada vez que se crea una instancia de un tipo construido con un tipo de referencia como parámetro, independientemente del tipo que sea, el tiempo de ejecución reutiliza la versión especializada creada anteriormente del tipo genérico. Esto es posible porque todas las referencias tienen el mismo tamaño.
Por ejemplo, supongamos que tenía dos tipos de referencia, una Customer
clase y una Order
clase, y también supongamos que creó una pila de Customer
tipos:
class Customer { }
class Order { }
Stack<Customer> customers;
En este momento, el tiempo de ejecución genera una versión especializada de la Stack<T> clase que almacena las referencias de objeto que se rellenarán más adelante en lugar de almacenar datos. Supongamos que la siguiente línea de código crea una pila de otro tipo de referencia, que se denomina Order
:
Stack<Order> orders = new Stack<Order>();
A diferencia de los tipos de valor, no se crea otra versión especializada de la Stack<T> clase para el Order
tipo. En su lugar, se crea una instancia de la versión especializada de la Stack<T> clase y la orders
variable se establece para hacer referencia a ella. Suponga que encuentra una línea de código para crear una pila de tipo Customer
:
customers = new Stack<Customer>();
Al igual que con el uso anterior de la Stack<T> clase creada mediante el Order
tipo , se crea otra instancia de la clase especializada Stack<T> . Los punteros contenidos en ellos se establecen para hacer referencia a un área de memoria del tamaño de un Customer
tipo. Dado que el número de tipos de referencia puede variar de forma salvaje de programa a programa, la implementación de C# de genéricos reduce considerablemente la cantidad de código al reducir a un número de clases especializadas creadas por el compilador para clases genéricas de tipos de referencia.
Además, cuando se crea una instancia de una clase genérica de C# mediante un tipo de valor o un parámetro de tipo de referencia, la reflexión puede consultarla en tiempo de ejecución y tanto su tipo real como su parámetro de tipo se pueden determinar.