¡Hoy la cosa va de noticias!. Podéis descargar una versión Pre-Release en el siguiente enlace.
Microsoft Pre-release Software Visual Studio 2010 and .NET Framework 4.0 Community Technology Preview (CTP).
Gracias a Pedro por el aviso
.
El pasado jueves (23-10-08) Microsoft publicó una posible vulnerabilidad en el kernel de Windows que podría permitir en las máquinas afectadas la ejecución remota de código por medio de una solicitud RPC.
Los sistemas más afectados son Windows 2000, Windows XP y Windows Server 2003. No obstante, también hay actualizaciones de seguridad para Windows Vista y Windows Server 2008.
Para más información sobre esta noticia, así como todas las actualizaciones de seguridad y la manera de solucionar este problema podeís visitar el siguiente enlace:
http://www.microsoft.com/spain/technet/security/Bulletin/MS08-067.mspx
Antes de comenzar hablar directamente de los
indizadores, vamos a ver unos ejemplos que nos ayudarán a comprender
mejor las ventajas del uso de la indexación.
Supongamos
que tenemos una clase llamada “Personas” que lo único que hace es
guardar los nombres de distintas personas. Parece lógico que para
implementar esta clase definamos una matriz de tipo String que almacene
los nombres. Por ejemplo podríamos pensar en hacer esto:
class Personas
{
public string[] Nombre = new string[3];
}
Así tenemos definida una clase que almacena 3 nombres de personas en
una matriz de tipo String. Para utilizar solo tendríamos que hacer esto:
static void Main(string[] args)
{
Personas persona = new Personas();
//Rellenamos la matriz.
persona.Nombre[0] = "Mariano";
persona.Nombre[1] = "Pedro";
persona.Nombre[2] = "Maria";
//Mostrar el contenido de la matriz.
foreach (string item in persona.Nombre)
Console.WriteLine(item);
Console.ReadLine();
}
Desde luego esto funciona pero al tener declarada
la matriz como pública no contribuimos a proteger debidamente los
miembros de la clase.
Una solución a este problema de proteger los miembros es declararlos como privados. Es decir:
class Personas
{
private string[] Nombre = new string[3];
}
¿Cómo accedemos ahora a los elementos de la matriz
“persona”?. Al estar declarada como privada no tenemos acceso a este
campo por medio de un objeto de la clase “Personas”.
La
solución es muy sencilla. Añadimos a nuestra clase dos métodos
públicos, una para asignar nombres en la matriz (método Añadir) y otro
para recuperar los valores de los elementos almacenados en la matriz
(método Obtener).
class Personas
{
private string[] Nombre = new string[3];
public void Añadir(string nom, int i)
{
Nombre[i] = nom;
}
public string Obtener(int i)
{
return Nombre[i];
}
}
Ahora la clase podemos utilizarla por medio de los métodos de la siguiente forma.
Personas persona = new Personas();
//Rellenamos la matriz.
persona.Añadir("Mariano", 0);
persona.Añadir("Pedro", 1);
persona.Añadir("Maria", 2);
//Mostrar el contenido de la matriz.
for (int i = 0; i < 3; i++)
Console.WriteLine(persona.Obtener(i));
Console.ReadLine();
Es perfecto. Todo funciona correctamente y tenemos el nivel de protección que deseábamos.
Sin
embargo no estamos utilizando la matriz como si fuera una matriz. No
accedemos a los elementos por medio de un índice dentro del operador de
indexación [] que tantas veces hemos visto en las matrices. Hagamos lo
siguiente:
class Personas
{
private string[] Nombre = new string[3];
public string this[int i]
{
get { return Nombre[i]; }
set { Nombre[i] = value; }
}
}
La forma de utilizar un objeto de clase “Personas”, ahora que ya esta indexada, es la siguiente:
Personas persona = new Personas();
//Rellenamos la matriz.
persona[0] = "Mariano";
persona[1] = "Pedro";
persona[2] = "Maria";
//Mostrar el contenido de la matriz.
for (int i = 0; i < 3; i++)
Console.WriteLine(persona[i]);
Console.ReadLine();
Como vemos la definición de la clase tiene mucho
menos código al no tener que implementar dos métodos, esto ya es una
ventaja. La forma de obtener y establecer los elementos de la matriz es
mucho más natural.
Si una propiedad es una
especie de “método inteligente” de las variables definidas en una
clase. La indexación es “método inteligente” de las matrices definidas
en nuestras clases.
No lo dudéis, si tenéis una clase con varios campos que almacenan datos en matrices, ¡indexar la clase!.
Aquí tenemos un pequeño y sencillo ejemplo de cómo pasarle a un mismo
método diferentes matrices con longitudes diferentes. Al definir los
parámetros del método como params podemos tener un mismo método (con diferentes llamadas) que ejecute operaciones con diferentes longuitudes de matrices.
class Params
{
static void Main(string[] args)
{
//Creamos dos matrices con longuitudes distintas.
byte[] pares = new byte[4] { 2, 4, 6, 8 };
byte[] impares = new byte[5] { 1, 3, 5, 7, 9 };
//Llamamos al mismo método Mostrar() pasandole como argumento
//matrices con diferente longitud y una serie numérica.
Console.WriteLine("Matriz de pares");
Mostrar(pares);
Console.WriteLine("\nMatriz de impares");
Mostrar(impares);
Console.WriteLine("\nSerie numérica");
Mostrar(23, 43, 54, 65, 76, 45, 34, 23, 34);
Console.ReadLine();
}
static void Mostrar(params byte[] mtzArgs)
{
foreach (byte i in mtzArgs)
Console.WriteLine(i.ToString());
}
}
La salida de consola es la siguiente:
El propósito de este código es mostrar cómo se cambia el tamaño de una matriz en C#.
Antes
de seguir con el código, es necesario tener conocimientos previos sobre
declaración e inicialización de matrices, así como de los métodos y
propiedades de la clase Array. Aquí os dejo unos links de la
documentación MSDN:
1- Declarar e inicializar matrices.
2- Utilizar Foreach en matrices.
3- Métodos y propiedades de la clase Array.
En realidad cambiar el tamaño de una matriz no tiene mucho misterio. Supongamos una matriz de tipo int llamada miMatriz:
int[] miMatriz = { 1, 2, 3 };
Supongamos ahora que queremos ampliarla en 4 elementos, es decir, conseguir una matriz de 7 elementos. Es muy sencillo:
miMatriz = new int[miMatriz.Length + 4];
Todo
correcto. Ahora tenemos una matriz de tipo int llamada miMatriz que
puede contener 7 elementos. Pero ahora vienen las preguntas:
¿Qué ha ocurrido con los datos de la matriz original { 1, 2, 3 }?.
¿La nueva matriz contiene los datos originales?.
La
respuesta es que los datos originales { 1, 2, 3 } se han perdido al
obtener una nueva matriz de 7 elementos “vacios”, es decir, la nueva
matriz contiene { 0, 0, 0, 0, 0, 0, 0 }. Veámoslo en el código.
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Declarar e inicilizar una matriz de tipo int
int[] miMatriz = { 1, 2, 3 };
// Mostrar el contenido de MiMatriz
Console.WriteLine("Esta es miMatriz original...");
foreach (int x in miMatriz)
Console.WriteLine(x);
Console.WriteLine();
// Ampliamos miMatriz y mostramos su contenido
miMatriz = new int[miMatriz.Length + 4];
Console.WriteLine("Esta es miMatriz ampliada...");
foreach (int x in miMatriz)
Console.WriteLine(x);
Console.ReadLine();
}
}
}
Como podemos observar los datos de la matriz se han perdido. ¿Qué debemos hacer para ampliar una matriz en C# sin perder los datos?. La única forma de conseguirlo es creando una copia de la matriz que queremos ampliar. Para clarificarlo sigamos estos 4 pasos:
PASO 1. Declarar e inicializar una matriz “de copia” con el mismo tamaño que la matriz original.
PASO 2. Copiar el contenido de la matriz original en la matriz “copia”.
PASO 3. Aumentar el tamaño de la matriz original.
PASO 4. Copiar el contenido de la matriz “copia” en la matriz original ya ampliada.
Veamos el código de estos 4 pasos.
class Program
{
static void Main(string[] args)
{
// Declarar e inicilizar una matriz de tipo int
int[] miMatriz = { 1, 2, 3 };
// Mostrar el contenido de MiMatriz
Console.WriteLine("Esta es miMatriz original...");
foreach (int x in miMatriz)
Console.WriteLine(x);
Console.WriteLine();
// PASO 1:
// Declarar e inicializar una matriz llamada Micopia
int[] miCopia = new int[miMatriz.Length];
// PASO 2:
// Copiar el contenido de miMatriz en miCopia
miMatriz.CopyTo(miCopia, 0);
// PASO 3:
// Cambiar el tamaño de miMatriz (en este caso lo aumentamos en 4)
miMatriz = new int[miMatriz.Length + 4];
// PASO4:
// Copiar el contenido de miCopia en miMatriz ya ampliada
miCopia.CopyTo(miMatriz, 0);
// Mostrar el contenido de miMatriz ampliada
Console.WriteLine("Esta es miMatriz ampliada...");
foreach (int x in miMatriz)
Console.WriteLine(x);
Console.ReadLine();
}
}
De
esta forma obtenemos una matriz ampliada conservando los datos pero en
definitiva este comportamiento es muy pobre. Es recomendable trabajar
con ArrayList.