lunes, 15 de septiembre de 2014

12.- Instrucciones de Selección

Las instrucciones son acciones que realiza el programa. Existen acciones comunes como la declaración de variables, la asignación de valores, la llamada a métodos, el recorrido en bucle de una colección y la creación de bifurcaciones a uno u otro bloque de código en función de una condición. El orden en que se ejecutan las instrucciones en un programa se denomina flujo de control o flujo de ejecución.
Para C#, una instrucción puede estar compuesta por una única línea de código que finaliza en un punto y coma o por una serie de instrucciones de una línea incluidas en un bloque.  Como ya hemos visto, un bloque de instrucciones se encierra entre llaves {} y pueden contener bloques anidados. A continuación enumero las categorías:
  • Instrucciones de selección (if, else, switch, case)
  • Instrucciones de iteración (do, for, foreach, in, while)
  • Instrucciones de salto (break, continue, default, goto, return, yield)
  • Instrucciones de control de excepciones (throw, try-catch, try-finally, try-catch-finally)
  • Checked y unchecked (checked, unchecked)
  • Instrucción fixed (fixed)
  • Instrucción lock

En VB.NET

En Visual Basic, una instrucción es una instrucción completa.  Puede contener palabras clave, operadores, variables, constantes y expresiones y cada instrucción como en C#, pertenece a cada una de las categorías siguientes:
Instrucciones de declaración, que dan nombre a una variable, constante o procedimiento y también pueden especificar un tipo de datos.
Instrucciones ejecutables, que inician acciones.  Estas instrucciones pueden llamar a un método o función, y pueden repetirse en bloques de código o crear una bifurcación en otro bloque de código. Las instrucciones ejecutables incluyen instrucciones de asignación, que asignan un valor o expresión a una variable o constante.

En este capítulo, vamos a ver las instrucciones de selección para C# y las instrucciones ejecutables para VB.NET.

¿Empezamos por C#? Venga, pues una instrucción de selección, hace que el programa vaya a un determinado punto dependiendo de que cierta condición sea verdadero o falso (true o false). Las palabras if, else, switch, case y default son las palabras clave en las instrucciones de selección. Como son palabras clave, no pueden usarse como variables o nombres de métodos ya que el compilador nos daría un error.
La instrucción if identifica que sentencia debe ejecutarse dependiendo de un valor booleano (verdadero o falso, true o false), vemos un ejemplo:

bool condition = true;

if (condition)
{
Console.WriteLine("La variable tiene un valor true");
}
else
{
Console.WriteLine("La variable tiene un valor false.");
}

Analicemos el código. Si la variable es true, (verdadera), visualizaremos en pantalla el texto de “La variable tiene un valor true”, pero si el valor lo cambiáramos a false, veríamos el segundo mensaje “La variable tiene un valor false”. El contenido donde se dirigirá el flujo del programa, se encuentra encerrado entre llaves {}, a continuación tenemos la palabra clave else y otras dos llaves con el contenido donde se redirigirá el programa cuando la condición es false.
En el siguiente ejemplo, declaramos una variable con valor entero y le asignamos el valor 8 y en la instrucción comparamos ese valor m para ver si es mayor que 10, ¿es mayor 8 que 10 (entre paréntesis)? Yo creo que no, pues entonces se aparecerá el mensaje “La variable tiene un valor false”.

int m = 8;

if (m > 10)
{
Console.WriteLine("La variable tiene un valor true");
}
else
{
Console.WriteLine("La variable tiene un valor false.");
}

También podríamos comparar si un texto es igual a otro mediante el operador ==

string texto = “mi_texto”;

if (texto == “mi_texto”)
{
Console.WriteLine("La variable tiene un valor true");
}

También existe una combinación de if else y es que además podemos hacer una comparativa if y si falla esta, podemos hacer de nuevo otra comparación else if y si fallaran todas las instrucciones else if, redirigir el programa a la instrucción else.

int m = 8;

if (m > 10)
{
Console.WriteLine("La variable tiene un valor true");
}
else if (m == 8)
{
Console.WriteLine("La variable tiene un valor igual a 8");
}
else
{
Console.WriteLine("La variable tiene un valor false.");
}


La instrucción if tiene una forma simplificada como la que os represento

if (m > 10) {Console.WriteLine("La variable tiene un valor true");}
else {Console.WriteLine("La variable tiene un valor false.");}
(Esta versión es igual que las anteriores, pero con las llaves en la misma línea)
o
if (m > 10) Console.WriteLine("La variable tiene un valor true");
else Console.WriteLine("La variable tiene un valor false.");


Consejo: cuando no sepáis como funciona una instrucción, acudid a la referencia de msdn, ahí tenéis todo

Otra instrucción de selección es switch en la que se redirige el programa a la lista de candidatos, en el siguiente caso, como es igual a 1, se redirigirá a la zona donde se imprimirá en pantalla “Caso 1”. Si por ejemplo el valor de la variable tuviera un valor de 17, como no existe ningún caso que valga 17, se ejecutaría la instrucción Default.
La palabra clave break, hace que una vez ejecutado el caso concreto, el programa se redirija fuera de la instrucción y no ejecute nada más dentro de esta.

int casoSwitch = 1;
switch (casoSwitch)
{
case 1:
Console.WriteLine("Caso 1");
break;
case 2:
Console.WriteLine("Caso 2");
break;
default:
Console.WriteLine("Caso Default");
break;
}

En el lenguaje “der Waki”. ¿Existe algún caso que sea igual a 2? Pués claro!! Ir hasta el caso 2 e imprimir en pantalla “Caso 2”.

Otro caso, sería poder agrupar casos. En este concreto, hemos agrupado el caso 2,3 y 8, de modo que si la variable vale alguno de ellos, aparecerá el texto “Caso 2, 3 u 8”

int casoSwitch = 3;
switch (casoSwitch)
{
case 1:
Console.WriteLine("Caso 1");
break;
case 2:
case 3:
case 8:
Console.WriteLine("Caso 2, 3 u 8");
break;
default:
Console.WriteLine("Caso Default");
break;
}

En Visual Basic .NET es muy parecido todo, pero existen algunas variaciones, primero que no existen llaves como en C#, estas se cambian por palabras clave, entonces para iniciar una instrucción if, esta comienza por lo mismo If, se añade la condición (sin paréntesis), palabra clave Then (entonces en inglés), el contenido del código que se ejecutará cuando sea verdadero, ElseIf o Else cuando queremos efectuar nuevas comparativas o la condición es falsa respectivamente y por fin le decimos al compilador que la instrucción finaliza con End If. ¿Bien? Prácticamente es igual!

Dim m As Integer = 8

If m > 10 Then
Console.WriteLine("La variable tiene un valor true")
ElseIf m = 8 Then
Console.WriteLine("La variable tiene un valor igual a 8")
Else
Console.WriteLine("La variable tiene un valor false.")
End If

Para la instrucción switch iniciamos con Select Case y expresión Switch. Luego los casos, código del caso y salida de la instrucción Select Case.

Dim casoSwitch As Integer = 3
Select Case casoSwitch
Case 1
Console.WriteLine("Caso 1")
Exit Select
Case 2, 3, 8
Console.WriteLine("Caso 2, 3 u 8")
Exit Select
Case Else
Console.WriteLine("Caso Default")
Exit Select
End Select

Igual pero con otras palabras!! Same, but with other words!!
Y si encima .NET, te permite escribir en varios lenguajes, pues que más da el que uses!! el que más fácil te resulte, ¿no?


Saludos “der Waki”

Nota: Si utilizáis Visual Studio, escribid dentro de un método la palabra if y pulsáis la tecla TAB dos veces. OHHH!! el fragmento de código, se escribe solo!!!

lunes, 8 de septiembre de 2014

11.- Los campos, variables locales y tipos.


Vamos a tratar los campos, las variable locales y los tipos mediante una "minientrega".
Los campos, como ya dijimos, son variables declaradas a nivel de clase. Estos campos tienen como es lógico sus modificadores, es decir, pueden ser public, protected, prívate.
Aconsejo, no usar los campos como públicos sino privados o protegidos. ¿Por qué? Pues porque para ello ya usamos las propiedades y el campo lo que hace es respaldar el almacenamiento de estas.
Bueno hasta ahora no hemos descubierto nada, puesto que es repaso de lo aprendido, cuando declaramos un campo, lo definimos con un tipo, un número entero, doble precisión, fecha, cadena de texto, etc. Estos tipos pueden convertirse entre unos y otros, siempre que el compilador pueda hacerlo, en caso contrario provocaría un error. Puedo convertir una fecha a texto, pero lo que no puedo hacer es convertir la palabra “hola” en una fecha, el compilador se quejaría, ¿no?.
Una vez declarada una variable, ésta no se puede volver a declarar con un nuevo tipo y tampoco se le puede asignar un valor que no sea compatible con su tipo declarado. Por ejemplo, no puede declarar int y a continuación, asignarle un valor booleano de true. Sin embargo, los valores pueden convertirse en otros tipos, por ejemplo, cuando se asignan a variables nuevas o se pasan como argumentos de método.
Los tipos son:
Nombre de tipo
Descripción
System.Object
Clase base para todos los tipos. Puede almacenar cualquier cosa
System.String
Cadena de texto.
System.SByte
Byte con signo de 8 bits.
System.Byte
Byte sin signo de 8 bits.
System.Intl6
Valor de 16 bits con signo.
System.Ulntl6
Valor de 16 bits sin signo.
System.Int32
Valor de 32 bits con signo.
System.Ulnt32
Valor de 32 bits sin signo.
System.Int64
Valor de 64 bits con signo.
System.Ulnt64
Valor de 64 bits sin signo.
System.Char
Carácter unicode de 16 bits.
System.Single
Valor en coma flotante del IEEE de 32 bits.
System.Double
Valor en coma flotante del IEEE de 64 bits.
System.Boolean
Valor booleano (true!false).
System.Decimal
Tipo de datos de 128-bit igual a 28 o 29 dígitos. Principalmente utilizado para aplicaciones financieras, donde se requiere un alto grado de precisión.
 
Todos los tipos tienen un alias en el lenguaje de programación usado. ¿Y que es un alias?, pues un modo abreviado de acceder a ellos de una forma más rápida. Estos alias o nombres, no pueden ser utilizados para nombrar variables, están protegidos por el compilador, de modo que si intento declarar una variable con el nombre double, el compilador chillaría!
Y ¿por qué el tipo? Pues entre otras cosas, el tipo determina el almacenamiento interno en la memoria donde se guarda esta variable, el valor máximo y mínimo que puede representar, los miembros de clase que contiene (porque son clases), los tipos de operaciones que se pueden realizar con ellas, el tipo del que hereda y la ubicación en la memoria cuando se están en tiempo de ejecución. Con todo esto, el compilador se encarga de de comprobar que todos hacen las cosas como deben hacerlas.
Ejemplo.
C#
int a = 5;            
int b = a + 2; //Esto funciona, suma 5 + 2 = 7
 
bool test = true;
 
int c = a + test; // Error. El operador '+' no puede sumar una variable de número con una variable tipo booleana.
 
 
string d = a.ToString() + test.ToString(); // Esto no da error ya que el resultado es ‘5True’, ahora las variable tipo número y booleana, las he convertido antes a texto y lo que ha hecho, ha sido concatenarlas
 
VB.NET
Dim a As Integer = 5
            Dim b As Integer = a + 2
            'Esto funciona, suma 5 + 2 = 7
            Dim test As Boolean = True
 
            Dim c As Integer = a + test
            ' Error. El operador '+' no puede sumar una variable de número con una variable tipo booleana.
 
            Dim d As String = a.ToString() & test.ToString()
            ' Esto no da error ya que el resultado es ‘5True’, ahora las variable tipo número y booleana, las he convertido antes a texto y lo que ha hecho, ha sido concatenarlas
 
No se si os habéis dado cuenta, pero cuando declaramos una variable con su tipo, en la misma declaración es posible asignarle un valor, de este modo no tenemos porque volver a escribirla y asignarle un valor.
Bueno, pues todas estas cosas, además las podemos realizar dentro de un método y en este caso, la variable se convierte en local del método y no es accesible nada más que dentro de este y tampoco, nos permitirá declarar una variable con el mismo nombre dentro del método.
¿Cuáles son los más utilizados? Pues depende para que los vayamos a usar; ahí viene cuando diseñamos la clase y debemos determinar qué valores van a usar los miembros de clase.
Por ejemplo, dentro de un método voy a incluir un contador dentro de un bucle y cada vez que se repita, se sumará la cantidad de 1; sé que “jamás” no sobrepasará el valor de 10000, vamos que no llegará al valor de 10000, pues creo que si declaro una variable de tipo entero (16 bit) será más que suficiente, (valor mínimo -2147483647 y máximo 2147483647 ala!!!) ahora si el valor que voy a almacenar es el resultado de una división y necesito un aproximación alta, utilizaré un doublé (valor mínimo 5,0×10-324y valor máximo 1,7×10308. Vaya cifras astronómicas!, ¿no? pues depende para que, a veces se quedan cortas.
Pues lo prometido es deuda, entrega corta y a programar!! Practicad mucho!!
Saludos “der Waki”

sábado, 6 de septiembre de 2014

10.- Las propiedades


Como ya dijimos, las propiedades es una mezcla entre método y campo, puesto que almacenan valores y además nos permiten hacer cálculos sobre ellos. Para el que accede a la propiedad, la ve como un campo.
Además, son miembros de clase que nos permiten leer, escribir o calcular un campo privado de la clase, es decir, nos permite leerlo, cambiarle su valor o calcularle uno nuevo.
Una propiedad genérica, tiene la siguiente estructura:
  • Contiene un descriptor Get. Se utiliza para leer la propiedad. Una propiedad sin este valor, se considera de solo escritura, puesto que no es posible leerla.
  • Contiene un descriptor Set. Se utiliza para asignar un valor a la propiedad. Si este descriptor no existiera, la propiedad sería solo de lectura y por tanto, sería como cuando vimos la constante, que era un campo de solo lectura.
  • Tiene un campo del mismo tipo que la propiedad y asociado a esta.
Las propiedades no son campos, por tanto no podemos pasar como argumento en un método una propiedad.
¿Qué usos le podemos dar a las variables? Pues podemos usarlas para validar datos antes de permitir un cambio, exponer los datos de forma transparente obtenidos desde otro origen o cuando se realiza una acción, por ejemplo si cambiamos su valor, se genera un evento avisándonos de que la propiedad ha cambiado.
¿Dónde se declaran las propiedades? Las propiedades se declaran a nivel de clase mediante el tipo, el nombre de la propiedad, el descriptor get y el descriptor set.
Ejemplo. En la siguiente propiedad, declaramos un campo month y le asignamos el valor 7. Acto seguido declaramos la propiedad pública Month y en la cual si nosotros solicitáramos su lectura, nos daría el valor del campo month, en este caso, nos daría el valor 7. Si dijéramos que la propiedad Month vale ahora 10 (Octubre), en el descriptor set, comprobaría que el valor que le pasamos es mayor que 0, que como mínimo vale 1 y menor que 13, que como máximo valga 12. Una vez efectuada la comprobación le asignaría el valor a la propiedad. ¿Qué ocurriría si le asignamos el valor 15? Pues como no cumple las condiciones de mayor de 0 y menor de 13 y no se asignaría ningún valor a la propiedad quedando en su estado anterior. El valor value, es el valor que asignamos a la propiedad. ¿bien?
C#
        private int month = 7;  // el campo month
    public int Month        // La propiedad Month
    {
        get
        {
            return month;
        }
        set
        {
            if ((value > 0) && (value < 13))
            {
                month = value;
            }
        }
    }
VB.NET
        Private m_month As Integer = 7' el campo month
        Public Property Month() As Integer' La propiedad Month
            Get
                Return m_month
            End Get
            Set(value As Integer)
                If (value > 0) AndAlso (value < 13) Then
                    m_month = value
                End If
            End Set
        End Property

Otro ejemplo con nuestra clase preferida, la clase Vehiculo. Asignamos un propiedad a esta clase llamada Matricula y otra Potencia, pues vamos a crear una instancia de esta y vamos a leer y escribir sus propiedades.
C#
static void Main(string[] args)
{
            Console.WriteLine ("Comienza la App");
     Vehiculo miVehiculo = new Vehiculo();

            miVehiculo.Potencia = 120;
            miVehiculo.Matricula = "0000 XXX";
            Console.WriteLine(miVehiculo.Potencia);
            Console.WriteLine(miVehiculo.Matricula);
            Console.WriteLine("Pulse INTRO para finalizar..");
            Console.ReadLine();
}
class Vehiculo
{
        public Vehiculo()
        {
            // código utilizado al instanciar la clase
        } 
        private double _potencia;  
        public double Potencia
        {
            get { return _potencia; }
            set { _potencia = value; }
        }
        private string _matricula;
        public string Matricula
        {
            get { return _matricula; }
            set { _matricula = value; }
        }
}
VB.NET
        Private Shared Sub Main(args As String())
            Console.WriteLine("Comienza la App")
            Dim miVehiculo As New Vehiculo()
            miVehiculo.Potencia = 120
            miVehiculo.Matricula = "0000 XXX"
            Console.WriteLine(miVehiculo.Potencia)
            Console.WriteLine(miVehiculo.Matricula)
            Console.WriteLine("Pulse INTRO para finalizar..")
            Console.ReadLine()
        End Sub 
        Private Class Vehiculo
            ' código utilizado al instanciar la clase
            Public Sub New()
            End Sub 
            Private _potencia As Double
            Public Property Potencia() As Double
                Get
                    Return _potencia
                End Get
                Set(value As Double)
                    _potencia = value
                End Set
            End Property 
            Private _matricula As String
            Public Property Matricula() As String
                Get
                    Return _matricula
                End Get
                Set(value As String)
                    _matricula = value
                End Set
            End Property
        End Class 
En este ejemplo, desde el método de clase Main, creamos un objeto Vehículo llamado miVehiculo, le asignamos a la propiedad Potencia un valor de 120 , a la propiedad de Matrícula 0000 XXX y una vez asignadas, las imprimimos por pantalla.
¿Qué ocurre dentro de las propiedades? Cuando le asignamos un valor a la Propiedad Potencia, estamos accediendo al descriptor set dándole al valor del campo _potencia, el valor asignado de 120 pero en el siguiente paso, cuando lo imprimimos por pantalla accedemos al descriptor get y este lo que hace es ir a buscar el campo privado de clase _potencia y devuelve su valor que es 120. Así de fácil.
Otro ejemplo un poco más complejo.
C#
class Cuadrado
    {
        public double _lado;
        public Cuadrado(double s)  //constructor
        {
            _lado = s;
        }
        public double Area
        {
            get
            {
                return _lado * _lado;
            }
            set
            {
                _lado = System.Math.Sqrt(value);
            }
        }       
        public double Volumen
        {
            get
{ return _lado * _lado * _lado; }
            set
{ _lado =System.Math.Pow( value, 1 / 3); }
       } 
static void Main(string[] args)
{
      Cuadrado MiCuadrado = new Cuadrado(4);
      Console.WriteLine(MiCuadrado.Area); // imprime por pantalla 16
      MiCuadrado.Area = 100; // ahora el lado vale 10, pero no lo vemos porque es un camp privado de clase
          Console.WriteLine(MiCuadrado.Volumen); // imprime por pantalla 1000
 }

VB.NET
Class Cuadrado
        Public _lado As Double
        Public Sub New(s As Double)
            'constructor
            _lado = s
        End Sub 
        Public Property Area() As Double
            Get
                Return _lado * _lado
            End Get
            Set(value As Double)
                _lado = System.Math.Sqrt(value)
            End Set
        End Property
        Public Property Volumen() As Double
           Get
                Return _lado * _lado * _lado
           End Get
           Set(value As Double)
               _lado = System.Math.Pow(value, 1 \ 3)
           End Set
        End Property
End Class
 
Private Shared Sub Main(args As String())
Dim MiCuadrado As New Cuadrado(4)
            Console.WriteLine(MiCuadrado.Area)
            ' imprime por pantalla 16
            MiCuadrado.Area = 100
            ' ahora el lado vale 10, pero no lo vemos porque es un camp privado de clase
End Sub
Creamos una clase Cuadrado a la cual le agregamos una propiedad llamada Area con un campo llamado _lado. En el constructor de la clase, (lo primero que hace una clase cuando se instancia), le agregamos un parámetro s, de modo que cuando instanciemos la clase Cuadrado, nos pedirá que le pasemos un argumento, en este caso el valor del lado el cual automáticamente es asignado al campo _lado. Hasta aquí todo bien.
Si le pedimos al objeto cuadrado el valor de su Area, el descriptor get, obtendrá el valor de _lado y lo multiplicará por si mismo, obteniendo el Area que solicitamos.
Si ahora le dijéramos a este objeto que el valor de su Area es 100, el descriptor set calcularía la raíz cuadrada del área para asignar al campo _lado este valor, en este caso 10, por tanto al solicitarle que imprima por pantalla la propiedad Volumen, este ha calculado el nuevo valor del lado y el nuevo valor del volumen. Este es uno de los poderes secretos de las propiedades. Fantástico ¿no?
Ahora que sabemos que son las propiedades, más adelante crearemos algunas más complejas que nos avisen cuando cambie su valor generando eventos.
Saludos “der Waki”