Explora Libros electrónicos
Categorías
Explora Audiolibros
Categorías
Explora Revistas
Categorías
Explora Documentos
Categorías
VARGAS TORRES
TIPOS DE DATOS NATIVOS Y
HEREDADOS POR EL LENGUAJE DE
PROGRAMACION C#
Introducción
Cuando definimos un objeto debemos especificar su tipo. El tipo determina qué valores
puede almacenar ese objeto (clase y rango) y las operaciones que pueden efectuarse con él.
La estructura de tipos de C# es una gran novedad ya que establece una relación jerárquica
entre éstos, de manera que todos los tipos son clases y se construyen por herencia de la
clase base Objet. Esta particularidad hace que la creación y gestión de tipos de datos en C#
sea una de las principales novedades y potencialidades del lenguaje .
Objetivos
Objetivos Generales
1. Conocer los tipos de datos nativos y heredados por el lenguaje de programación e
Identificar cuáles son sus funciones
Objetivos específicos
1. Comprender el significado de los tipos de datos
2. Estudiar el uso y el funcionamiento de los tipos de datos
3. Aplicar los conocimientos en futuras actividades en clase
Desarrollo
System.Int32 a = 2;
int a = 2;
Cadenas de caracteres
string System.String ""
Unicode
Los tipos están definidos de manera muy precisa y no son dependientes del compilador o de
la plataforma en la que se usan.
La tabla anterior incorpora la columna Símbolo para indicar cómo debe interpretarse un
literal. Por ejemplo, 28UL debe interpretarse como un entero largo sin signo (ulong).
Todos los tipos enumerados son tipos valor, excepto string (que no debe confundirse con un
vector de caracteres) y Object que son tipos referencia. Recuerde, no obstante, que los
datos string se comportaban como un tipo valor ante la asgnación.
int i = 10;
string c = i.ToString();
e incluso:
string c = 10.ToString();
Esta manera por la que podemos manipular los datos básicos refleja la íntima relación entre
C# y la biblioteca de clase de .NET. De hecho, C# compila sus tipos básicos asociándolos a
sus correspondientes en .NET; por ejemplo, hace corresponder al tipo string) con la
clase System.String, al tipo int) con la clase System.Int32, etc. Así, se confirma que todo es
un objeto en C# (por si aún había alguna duda).
Aunque no comentaremos todos los métodos disponibles para los tipos básicos,
destacaremos algunos de ellos.
Todos los tipos tienen un método ToString() que devuelve una cadena (string) que
representa su valor textual.
char tiene propiedades acerca de su contenido (IsLetter, IsNumber, etc.) además
de métodos para realizar conversiones (ToUpper(), ToLower(), etc.)
El tipo básico string dispone, como puede suponerse, de muchos métodos
específicos, aún más que la clase string de la biblioteca estándar de C++.
Conversiones de tipos
Implícitas Explícitas
int x = 123456;
long y = x; // implicita
short z = (short) x; // explicita (riesgo)
float f1 = 40.0F;
long l1 = (long) f1; // explicita (riesgo por redondeo)
short s1 = (short) l1; // explicita (riesgo por desbordamiento)
int i1 = s1; // implicita, no hay riesgo
uint i2 = (uint) i1; // explicita (riesgo de error por signo)
En C# las conversiones de tipo (tanto implícitas como explícitas) en las que intervengan tipos
definidos por el usuario pueden definirse y particularizarse.
El tipo object
Por el sistema unificado de tipos de C#, todo es un objeto. C# tiene predefinido un tipo
referencia llamado object y cualquier tipo (valor o referencia, predefinido o definido por el
usuario) es en última instancia, de tipo object (con otras palabras puede decirse
que hereda todas las características de ese tipo).
object o;
todas estas instrucciones son válidas:
o = 10; // int
o = "Una cadena para el objeto"; // cadena
o = 3.1415926; // double
o = new int [24]; // vector de int
o = false; // boolean
Dado que todas las clases de .NET Framework se derivan de Object, todos los métodos
definidos en la clase Object están disponibles en todos los objetos del sistema. Las clases
derivadas pueden reemplazar, y de hecho reemplazan, algunos de estos métodos, entre los
que se incluyen los siguientes:
10
Una cadena para el objeto
3,1415926
System.Int32[]
False
System.Int32
System.String
System.Double
System.Int32[]
System.Boolean
Boxing (y su operación inversa, unboxing) permiten tratar a los tipos valor como objetos
(tipo referencia). Los tipos de valor, incluidos los struct y los predefinidos, como int, se
pueden convertir al tipo object (boxing) y desde el tipo object (unboxing).
void Polim(object o)
{
Console.WriteLine(o.ToString());
}
...
Polim(42);
Polim("abcd");
Polim(12.345678901234M);
Polim(new Point(23,45));
Boxing
Boxing es una conversión implícita de un tipo valor al tipo object. Cuando se realiza boxing
de un valor, se asigna una instancia de objeto y se copia el valor en el nuevo objeto.
int i = 123;
La siguiente instrucción aplica implícitamente la operación de boxing sobre la variable i:
object o = i;
El resultado de esta instrucción es crear un objeto o en la pila que hace referencia a un valor
del tipo int alojado en el heap. Este valor es una copia del valor del tipo de valor asignado a
la variable i. La diferencia entre las dos variables, i y o se muestra en la siguiente figura:
En definitiva, el efecto del boxing es el de cualquier otro tipo de casting pero:
int i = 123;
object o = (object) i;
Una vez que se ha hecho boxing sobre un dato y disponemos de un object no puede hacerse
demasiado con él ya que no pueden emplearse métodos o propiedades del tipo original: el
compilador no puede conocer el tipo original sobre el que se hizo boxing.
string s1 = "Hola";
object o = s1; // boxing
...
if (o.Lenght > 0) // ERROR
Una vez que se ha hecho boxing puede deshacerse la conversión (unboxing) haciendo
casting explícito al tipo de dato inicial.
string s2;
if (o is string)
s2 = (string) o; // unboxing
o alternativamente:
Ventajas del sistema unificado de tipos: las colecciones funcionan sobre cualquier tipo.
t.Add(0, "zero");
t.Add(1, "one");
t.Add(2, "two");
Puede accederse a cada uno de los caracteres de la cadena mediante índice, como ocurre
habitualmente en otros lenguajes, siendo la primera posición asociada al índice cero. Este
acceso, no obstante, sólo está permitido para lectura.
Por definición, un objeto String, incluida la cadena vacía (""), es mayor que una referencia
nula y dos referencias nulas son iguales entre sí. El carácter null se define como el
hexadecimal 0x00. Puede consultarse si una cadena es vacía empleando la propiedad
estática (sólo lectura) Empty: el valor de este campo es la cadena de longitud cero o cadena
vacía, "". Una cadena vacía no es igual que una cadena cuyo valor sea null.
string linea;
string [] palabras;
...
palabras = linea.Split (null); // null indica dividir por espacios
Vectores y matrices
Un vector (matriz) en C# es radicalmente diferente a un vector (matriz) en C++: más que una
colección de variables que comparten un nombre y accesibles por índice, en C# se trata de
una instancia de la clase System.Array, y en consecuencia se trata de una colección que se
almacena en el heap y que está bajo el control del gestor de memoria.
Todas las tablas que definamos, sea cual sea el tipo de elementos que contengan, son
objetos que derivan de System.Array. Ese espacio de nombres proporciona métodos para la
creación, manipulación, búsqueda y ordenación de matrices, por lo tanto, sirve como clase
base para todas las matrices de la CLR (Common Language Runtime).
En C# las tablas pueden ser multidimensionales, se accede a los elementos por índice,
siendo el índice inicial de cada dimensión 0.
Siempre se comprueba que se esté accediendo dentro de los límites. Si se intenta acceder a
un elemento de un vector (matriz) especificando un índice fuera del rango, se detecta en
tiempo de ejecución y se lanza una excepción IndexOutOfBoundsException.
La sintaxis es ligeramente distinta a la del C++ porque las tablas son objetos de tipo
referencia:
Un vector puede inicializarse a la misma vez que se declara. Las tres definiciones siguientes
son equivalentes:
Los vectores pueden dimensionarse dinámicamente (en tiempo de ejecución). Por ejemplo,
el siguiente código:
Console.ReadLine();
Num. casillas: 6
Contenido de VecDin = 0, 1, 2, 3, 4, 5,
Esta facilidad es una gran ventaja, aunque una vez que el constructor actúa y se crea una
instancia de la clase System.Array no es posible redimensionarlo. Si se desea una estructura
de datos con esta funcionalidad debe emplearse una estructura colección disponible
en System.Collections (por elemplo, System.Collections.ArrayList).
Una matriz dentada no es más que una tabla cuyos elementos son a su vez tablas,
pudiéndose así anidar cualquier número de tablas. Cada tabla puede tener un número
propio de casillas. En el siguiente ejemplo se pide el número de filas, y para cada fila, el
número de casillas de ésa.
// Mostrar resultado
Console.WriteLine ("Contenido de la matriz: ");
for (int f=0; f<TablaDentada.Length; f++)
{
for (int c=0; c<TablaDentada[f].Length; c++)
Console.Write (TablaDentada[f][c] + " ");
Console.WriteLine();
}
Console.ReadLine();
El resultado es:
Una estructura (struct) se emplea para definir nuevos tipos de datos. Los nuevos tipos así
definidos son tipos valor (se almacenan en la pila).
La sintaxis para la definición de estructuras es similar a la empleada para las clases (se
emplea la palabra reservada struct en lugar de class). No obstante,
p = [2,5]
p2 = [0,0]
Point p3;
crea una instancia de la clase Point en la pila sin iniciar (cuidado: no inicia p3 a null, no es un
tipo referencia). Por lo tanto, la instrucción:
p.x += 100;
int px = p.x; // p.x==102
p3.x = px; // p3.x==102
p2 = p; // p2.x==102, p2.y==5
p2.x += 100; // p2.x==202, p2.y==5
p3.y = p.y + p2.y; // p3.y==10
enum Tamanio {
Pequeño = 1,
Mediano = 3,
Grande = 5
Inmenso
}
En el ejemplo, el valor asociado a Inmenso es 6.
Color c1 = Color.Black;
Console.WriteLine((int) c1); // 0
Console.WriteLine(c1); // Black
Console.WriteLine(c1.ToString()); // Black
Color c2 = Color.White;
Console.WriteLine((int) c2); // 7
Console.WriteLine(c2.ToString()); // White
enum ModArchivo
{
Lectura = 1,
Escritura = 2,
Oculto = 4,
Sistema = 8
}
...
ModArchivo st = ModArchivo.Lectura | ModArchivo.Escritura;
...
Console.WriteLine (st.ToString("F")); // Lectura, Escritura
Console.WriteLine (Enum.Format(typeof(ModArchivo), st, "G")); // 3
Console.WriteLine (Enum.Format(typeof(ModArchivo), st, "X")); // 00000003
Console.WriteLine (Enum.Format(typeof(ModArchivo), st, "D")); // 3
[ CITATION Fra17 \l 12298 ]
Clases y objetos
Las clases son los tipos más fundamentales de C#. Una clase es una estructura de datos que
combina estados (campos) y acciones (métodos y otros miembros de función) en una sola
unidad. Una clase proporciona una definición para instancias de la clase, también conocidas
como objetos. Las clases admiten herencia y polimorfismo, mecanismos por los que
las clases derivadas pueden extender y especializar clases base.
C#Copiar
public class Point
{
public int X { get; }
public int Y { get; }
Las instancias de clases se crean mediante el operador new, que asigna memoria para una
nueva instancia, invoca un constructor para inicializar la instancia y devuelve una referencia
a la instancia. Las instrucciones siguientes crean dos objetos Point y almacenan las
referencias en esos objetos en dos variables:
C#Copiar
var p1 = new Point(0, 0);
var p2 = new Point(10, 20);
Parámetros de tipo
Las clases genéricas definen *parámetros de tipo _. Los parámetros de tipo son una lista de
nombres de parámetros de tipo entre paréntesis angulares. Los parámetros de tipo siguen
el nombre de la clase. Los parámetros de tipo pueden usarse luego en el cuerpo de las
declaraciones de clase para definir a los miembros de la clase. En el ejemplo siguiente, los
parámetros de tipo de Pair son TFirst y TSecond:
C#Copiar
public class Pair<TFirst, TSecond>
{
public TFirst First { get; }
public TSecond Second { get; }
Un tipo de clase que se declara para tomar parámetros de tipo se denomina _tipo de clase
genérica*. Los tipos de estructura, interfaz y delegado también pueden ser
genéricos. Cuando se usa la clase genérica, se deben proporcionar argumentos de tipo para
cada uno de los parámetros de tipo:
C#Copiar
var pair = new Pair<int, string>(1, "two");
int i = pair.First; // TFirst int
string s = pair.Second; // TSecond string
Clases base
Una declaración de clase puede especificar una clase base. Tras el nombre de clase y los
parámetros de tipo, agregue un signo de dos puntos y el nombre de la clase base. Omitir
una especificación de la clase base es igual que derivarla del tipo object. En el ejemplo
siguiente, la clase base de Point3D es Point. En el primer ejemplo, la clase base
de Point es object:
C#Copiar
public class Point3D : Point
{
public int Z { get; set; }
Una clase hereda a los miembros de su clase base. La herencia significa que una clase
contiene implícitamente casi todos los miembros de su clase base. Una clase no hereda la
instancia, los constructores estáticos ni el finalizador. Una clase derivada puede agregar
nuevos miembros a aquellos de los que hereda, pero no puede quitar la definición de un
miembro heredado. En el ejemplo anterior, Point3D hereda los miembros X y Y de Point, y
cada instancia de Point3D contiene tres miembros: X, Y y Z.
Existe una conversión implícita de un tipo de clase a cualquiera de sus tipos de clase
base. Una variable de un tipo de clase puede hacer referencia a una instancia de esa clase o
a una instancia de cualquier clase derivada. Por ejemplo, dadas las declaraciones de clase
anteriores, una variable de tipo Point puede hacer referencia a una instancia
de Point o Point3D:
C#Copiar
Point a = new Point(10, 20);
Point b = new Point3D(10, 20, 30);
Estructuras
C#Copiar
public struct Point
{
public double X { get; }
public double Y { get; }
C#Copiar
interface IControl
{
void Paint();
}
Las clases y los structs pueden implementar varias interfaces. En el ejemplo siguiente, la
clase EditBox implementa IControl y IDataBound.
C#Copiar
interface IDataBound
{
void Bind(Binder b);
}
Cuando una clase o un struct implementan una interfaz determinada, las instancias de esa
clase o struct se pueden convertir implícitamente a ese tipo de interfaz. Por ejemplo
C#Copiar
EditBox editBox = new EditBox();
IControl control = editBox;
IDataBound dataBound = editBox;
Enumeraciones
C#Copiar
public enum SomeRootVegetable
{
HorseRadish,
Radish,
Turnip
}
También puede definir un elemento enum que se usará de forma combinada como
marcas. La declaración siguiente declara un conjunto de marcas para las cuatro
estaciones. Se puede aplicar cualquier combinación de estaciones, incluido un valor All que
incluya todas las estaciones:
C#Copiar
[Flags]
public enum Seasons
{
None = 0,
Summer = 1,
Autumn = 2,
Winter = 4,
Spring = 8,
All = Summer | Autumn | Winter | Spring
}
C#Copiar
var turnip = SomeRootVegetable.Turnip;
Las variables de cualquier tipo se pueden declarar como que no aceptan valores NULL o que
admiten un valor NULL. Una variable que acepta valores NULL puede contener un
valor null adicional que no indica valor alguno. Los tipos de valor que aceptan valores NULL
(estructuras o enumeraciones) se representan mediante System.Nullable<T>. Los tipos de
referencia que no aceptan valores NULL y los que sí aceptan valores NULL se representan
mediante el tipo de referencia subyacente. La distinción se representa mediante metadatos
leídos por el compilador y algunas bibliotecas. El compilador proporciona advertencias
cuando se desreferencian las referencias que aceptan valores NULL sin comprobar primero
su valor con null. El compilador también proporciona advertencias cuando las referencias
que no aceptan valores NULL se asignan a un valor que puede ser null. En el ejemplo
siguiente se declara un elemento int que admite un valor NULL, y que se inicializa en null. A
continuación, establece el valor en 5. Muestra el mismo concepto con una cadena que
admite un valor NULL. Para más información, consulte Tipos de valor que admiten un valor
NULL y Tipos de referencia que aceptan valores NULL.
C#Copiar
int? optionalInt = default;
optionalInt = 5;
string? optionalText = default;
optionalText = "Hello World.";
Tuplas
C# admite _ tuplas*, lo que proporciona una sintaxis concisa para agrupar varios elementos
de datos en una estructura de datos ligera. Puede crear una instancia de una tupla
declarando los tipos y los nombres de los miembros entre ( y ), como se muestra en el
ejemplo siguiente:
C#Copiar
(double Sum, int Count) t2 = (4.5, 3);
Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
// Output:
// Sum of 3 elements is 4.5.
[ CITATION Bil21 \l 12298 ]
Conclusión
Los tipos de datos nativos y heredados nos da la facilidad de que C# admita los conceptos de
encapsulación, herencia y polimorfismo. Una clase puede heredar directamente de una
clase primaria e implementar cualquier número de interfaces.
Linkografía
Arturo, C. (06 de febrero de 2020). academia. Obtenido de academia:
https://www.academia.edu/22438329/PALABRAS_RESERVADAS_PARA_C_