Sunteți pe pagina 1din 22

Ejemplos c#

Ejemplo 1 En este ejemplo, se escribe un carcter desde el teclado y el programa comprueba si se trata de un carcter alfabtico. En ese caso, comprueba si es minscula o mayscula. En cada caso, se muestra el mensaje apropiado.
// statements_if_else.cs // if-else example using System; class IfTest { static void Main() { Console.Write("Enter a character: "); char c = (char)Console.Read(); if (Char.IsLetter(c)) { if (Char.IsLower(c)) { Console.WriteLine("The character is lowercase."); } else { Console.WriteLine("The character is uppercase."); } } else { Console.WriteLine("Not an alphabetic character."); } } }

Resultado
2

Resultados del ejemplo


Enter a character: 2 The character is not an alphabetic character.

A continuacin se ofrece otro ejemplo: Ejecucin N 2:


Enter a character: A The character is uppercase.

Ejecucin N 3:
Enter a character: h The character is lowercase.

Tambin es posible extender la instruccin if de modo que puedan controlarse varias condiciones, mediante la construccin else-if siguiente:
if (Condition_1) { // Statement_1; } else if (Condition_2) { // Statement_2; } else if (Condition_3) { // Statement_3; } else { // Statement_n; }

Ejemplo 2

Este ejemplo comprueba si el carcter especificado es una letra minscula, mayscula o un nmero. En cualquier otro caso, se tratar de un carcter no alfanumrico. El programa utiliza la anterior estructura else-if en escalera.
// statements_if_else2.cs // else-if using System; public class IfTest { static void Main() { Console.Write("Enter a character: "); char c = (char)Console.Read(); if (Char.IsUpper(c)) { Console.WriteLine("Character is uppercase."); } else if (Char.IsLower(c)) { Console.WriteLine("Character is lowercase."); } else if (Char.IsDigit(c)) { Console.WriteLine("Character is a number."); }

else { Console.WriteLine("Character is not alphanumeric."); } } }

Resultado
E

Resultados del ejemplo


Enter a character: E The character is uppercase.

A continuacin se ofrecen otros ejemplos de ejecuciones: Ejecucin N 2:


Enter a character: e The character is lowercase.

Ejecucin N 3:
Enter a character: 4 The character is a number.

Ejecucin N 4:
Enter a character: $ The character is not alphanumeric. BUCLES FOR Veamos la sintaxis para hacernos mejor a la idea:

for (var=inicial;condicin;siguientevalor) { Instrucciones } Como veis, tras la sentencia for se indican las especificaciones del bucle entre parntesis. Dichas especificaciones estn divididas en tres partes separadas por punto y coma: la parte de asignacin del valor inicial en primer lugar; la parte que verifica la continuidad del bucle (mediante una condicin) en segundo lugar; y la parte en que se calcula el siguiente valor en tercer lugar. Pongamos un ejemplo: vamos a calcular el factorial de un nmero dado, que se encuentra almacenado en la variable num. Se podra hacer de dos formas:

for (byte i=num; i>1 ; i--) { fact*=i; } O bien:

for (byte i=1; i<=num ; i++) { fact*=i; } Claro, para que esto funcione, la variable fact ha de valer 1 antes de que el programa comience a ejecutar el bucle. Bien, veamos ahora cmo se van ejecutando estas instrucciones paso a paso:

1 paso: for (byte i=num; i>1 ; i--) { fact*=i; } 4 paso: for (byte i=num; i>1 ; i--) { fact*=i; }

2 paso: for (byte i=num; i>1 ; i--) { fact*=i; } 5 paso: for (byte i=num; i>1 ; i--) { fact*=i; }

3 paso: for (byte i=num; i>1 ; i--) { fact*=i; } 6 paso: for (byte i=num; i>1 ; i--) { fact*=i; }

En primer lugar se asigna a la variable i el valor de num (vamos a suponer que num vale 3), es decir, despus del primer paso, el valor de i es 3. Posteriormente se comprueba si dicha variable es mayor que 1, es decir, si 3>1. Como la condicin del segundo paso se cumple se ejecuta el cdigo del bucle en el tercer paso, fact*=i, con lo que fact (que vala 1) ahora vale 3 (1*3). En el cuarto paso se asigna el siguiente valor a i (i--), con lo que, ahora, i valdr 2. En el quinto se vuelve a comprobar si i es mayor que 1, y como esto se cumple, el sexto paso vuelve a ejecutar el cdigo del bucle (de nuevo, fact*=i), con lo que ahora fact vale 6 (3*2). El sptimo paso es idntico al cuarto, es decir, se asigna el siguiente valor a la variable i (de nuevo, i--), con lo que ahora i valdra 1. El octavo paso es idntico al quinto, comprobando por lo tanto si i es mayor que 1. Sin embargo esta vez, la condicin no se cumple (1 no es mayor que 1, sino igual), por lo que la ejecucin saldra del bucle y ejecutara la siguiente lnea del programa que est fuera de l. Date cuenta de que el bucle se seguir ejecutando siempre que la condicin ( i>1 ) se cumpla, y dejar

de ejecutarse cuando la condicin no se cumpla. Por lo tanto, no habra sido vlido poner i==2 en lugar de i>1, ya que esta condicin se cumplira nicamente cuando num valiera 2, pero no en cualquier otro caso. Seras capaz de ver cmo funcionara el otro bucle? Venga, intntalo.

BUCLES FOR ANIDADOS

Efectivamente, se pueden colocar bucles for dentro de otros bucles for, con lo que obtendramos lo que se llaman los bucles for anidados. Son tambin muy tiles: por ejemplo, piensa que tienes almacenadas unas cuantas facturas en una base de datos, y quieres leerlas todas para presentarlas en pantalla. El problema est en que cada factura tiene una o varias lneas de detalle. Cmo podramos hacer para cargar cada factura con todas sus lneas de detalle? Pues usando bucles anidados. Colocaramos un bucle for para cargar las facturas, y otro bucle for dentro de l para que se cargaran las lneas de detalle de cada factura. As, el segundo bucle se ejecutar completo en cada iteracin del primer bucle. Veamos un ejemplo que nos aclare todo esto un poco ms:

using System; namespace BuclesAnidados { class BuclesAnidadosApp { static void Main() { for (int i=1; i<=3; i++) { Console.WriteLine("Factura nmero {0}", i); Console.WriteLine("Detalles de la factura"); for (int j=1; j<=3; j++) { Console.WriteLine(" } Console.WriteLine(); } string a=Console.ReadLine(); } } } Como ves, el bucle "j" est dentro del bucle "i", de modo que se ejecutar completo tantas veces como se itere el bucle i. Por este motivo, la salida en consola sera la siguiente:

Lnea de detalle {0}", j);

Factura nmero 1 Detalles de la factura Lnea de detalle 1 Lnea de detalle 2 Lnea de detalle 3 Factura nmero 2 Detalles de la factura Lnea de detalle 1 Lnea de detalle 2 Lnea de detalle 3 Factura nmero 3 Detalles de la factura Lnea de detalle 1 Lnea de detalle 2 Lnea de detalle 3

BUCLES WHILE

Bien, para los que no sepan ingls, "while" significa "mientras", de modo que ya os podis hacer la idea: un bucle while se repetir mientras una condicin determinada se cumpla, o sea, devuelva true. Veamos su sintaxis:

while (expresin bool) { Instrucciones } Efectivamente, las "Instrucciones" que se hallen dentro del bucle while se ejecutarn continuamente mientras la expresin de tipo boolean retorne true. Por ejemplo, podemos escribir un bucle while para pedir una contrasea de usuario. Algo as:

using System; namespace BuclesWhile { class BuclesWhileApp { static void Main() { string Clave="Compadre, cmprame un coco"; string Res=""; while (Res!=Clave) { Console.Write("Dame la clave: ");

Res=Console.ReadLine(); } Console.WriteLine("La clave es correcta"); string a=Console.ReadLine(); } } } En este pequeo ejemplo el programa pedir una y otra vez la clave al usuario, y cuando este teclee la clave correcta ser cuando finalice la ejecucin del mismo. As, la salida en la consola de este programa sera algo como esto (en rojo est lo que se ha tecleado durante su ejecucin):

Dame la clave: No quiero Dame la clave: Que no Dame la clave: eres contumaz, eh? Dame la clave: Vaaaaale Dame la clave: Compadre, cmprame un coco La clave es correcta BUCLES DO

Ciertamente, estos bucles tienen mucho que ver con los bucles while. La diferencia es que estos se ejecutan siempre al menos una vez, mientras que los bucles while, como acabamos de ver antes, pueden no ejecutarse ninguna vez. Veamos la sintaxis de los bucles "do":

do { Instrucciones } while (expresin bool); Como ves, tambin hay un while y una expresin boolean, pero en este caso se encuentra al final. De este modo, la ejecucin pasar siempre por las instrucciones del bucle una vez antes de evaluar dicha expresin. Vamos a rehacer el ejemplo anterior cambiando el bucle while por un bucle do:

using System; namespace BuclesDo { class BuclesDoApp { static void Main()

{ string Clave="Compadre, cmprame un coco"; string Res=""; do { Console.Write("Dame la clave: "); Res=Console.ReadLine(); } while (Res!=Clave); Console.WriteLine("La clave es correcta"); string a=Console.ReadLine(); } } } El resultado sera el mismo que antes. La diferencia est en que aqu dara exactamente lo mismo lo que valiera la variable Res antes de llegar al bucle, puesto que este se va a ejecutar antes de comprobar dicho valor, y al ejecutarse, el valor de Res se sustituye por lo que se introduzca en la consola. Por lo tanto, repito, los bucles do se ejecutan siempre al menos una vez.

Por otro lado tenemos otro tipo de bucle, los bucles foreach, pero no hablaremos de ellos hasta que hayamos visto arrays e indizadores. Tened un poco de paciencia, que todo se andar.

INSTRUCCIONES DE SALTO

Las instrucciones de salto permiten modificar tambin el flujo del programa, forzando la siguiente iteracin de un bucle antes de tiempo, o la salida del mismo o bien mandando la ejecucin directamente a un punto determinado del programa LA INSTRUCCIN BREAK

La instruccin break fuerza la salida de un bucle antes de tiempo o bien de una estructura de control de flujo condicional en la que se encuentre (un switch). Ahora nos fijaremos en los bucles, que es donde andamos. Pondremos un ejemplo sencillo: El siguiente programa escribir mltiplos de 5 hasta llegar a 100:

using System; namespace InstruccionBreak { class InstruccionBreakApp { static void Main() {

int num=0; while (true) { Console.WriteLine(num); num+=5; if (num>100) break; } string a=Console.ReadLine(); } } } Qu es eso de while (true)? Pues un bucle infinito. No decamos que dentro de los parntesis haba que colocar una expresin boolean? Pues entonces... true es una expresin boolean. De este modo, el bucle es infinito (claro, true siempre es true). Sin embargo, cuando la variable num tiene un valor mayor que 100 la ejecucin del bucle terminar, pues se ejecuta una instruccin break.

LA INSTRUCCIN CONTINUE

La instruccin continue fuerza la siguiente iteracin del bucle donde se encuentre (que puede ser un bucle for, while, do o foreach). Como esto se ve muy bien con un ejemplo, vamos con ello: El siguiente programa mostrar todos los nmeros del uno al veinte a excepcin de los mltiplos de tres:

using System; namespace InstruccionContinue { class InstruccionContinueApp { static void Main() { for (int i=1; i<=20; i++) { if (i % 3 == 0) continue; Console.WriteLine(i); } string a=Console.ReadLine(); } } }

En este ejemplo, el bucle for va asignando valores a la variable i entre 1 y 20. Sin embargo, cuando el valor de i es tres o mltiplo de tres (es decir, cuando el resto de la divisin entre i y 3 es cero) se ejecuta una instruccin continue, de modo que se fuerza una nueva iteracin del bucle sin que se haya escrito el valor de i en la consola. Por este motivo, apareceran todos los nmeros del uno al veinte a excepcin de los mltiplos de tres. GOTO S, C# mantiene vivo al "maldito goto". Si te digo la verdad, el goto, aparte de ser el principal baluarte de la "programacin des-estructurada", es un maestro de la supervivencia... de lo contrario no se explicara que siguiera vivo. De momento te dir que goto hace que la ejecucin del programa salte hacia el punto que se le indique. En realidad, el problema no es la instruccin goto en s misma, sino el uso inadecuado que algunos programadores le dan (pocos, gracias a Dios). Recordis de la entrega anterior el ejemplo en el que haba un switch en el que nos interesaba que se ejecutaran el caso 2 y el caso 3? Lo habamos resuelto con un if, de este modo:

switch (opcion) { case 1: descuento=10; break; case 2: case 3: if (opcion==2) regalo="Cargador de CD"; descuento=5; break; default: descuento=0; break; } En este ejemplo, si opcin vala 2 se asignaba una cadena a la variable regalo y, adems se asignaba 5 a la variable descuento. Pues bien, en este caso un goto habra resultado mucho ms natural, intuitivo y fcil de leer. Vemoslo:

switch (opcion) { case 1: descuento=10; break; case 2: regalo="Cargador de CD"; goto case 3; case 3: descuento=5; break;

default: descuento=0; break; } Como veis, hemos resuelto el problema anterior de un modo mucho ms natural que antes, sin tener que usar una sentencia if RECURSIVIDAD

los mtodos recursivos son mtodos que se llaman a s mismos. S que puede dar la impresin de que, siendo as, la ejecucin no terminara nunca, pero sin embargo esto no es cierto. Los mtodos recursivos han de finalizar la traza en algn punto. Vemoslo con un ejemplo. Recordis cmo habamos calculado el factorial mediante un bucle? Pues ahora vamos a hacerlo con un mtodo recursivo. Fjate bien:

static double Fact(byte num) { if (num==0) return 1; return num*Fact((byte) (num-1)); // Aqu Fact se llama a s mismo } Veamos, uso el tipo double porque es el que admite valores ms grandes, s, ms que el tipo Decimal, ya que se almacena en memoria de un modo diferente. Por otro lado, uso el tipo byte para el argumento sencillamente porque no tendra sentido usar un tipo que acepte nmeros mayores, ya que pasando de 170 el valor del factorial no cabe ni si quiera en el tipo double.

Ejemplo f#
La programacin funcional y la programacin imperativa se diferencian en un nivel muy fundamental y usted puede observarlo hasta en el cdigo ms simple:
int number = 0; number++;

Esto obviamente aumenta una variable en uno. Eso no es muy fascinante, pero considere una manera diferente en que podra resolver el problema:
const int number = 0; const int result = number + 1;

number an se aumenta en uno, pero no cambia de lugar. En vez de eso, el resultado se almacena como otra constante, dado que el compilador no permite modificar el valor de una constante.

considere este ejemplo:


string stringValue = "world!"; string result = stringValue.Insert(0, "hello ");

La funcin Insert compil la cadena hello world!, pero usted sabe que Insert no modifica el valor de la cadena de origen. Esto se debe a que las cadenas son inmutables en .NET.

Poner F# en funcionamiento
Si se resalta cdigo en Visual Studio y se presiona Alt+Intro, el cdigo se enva a F# Interactive. Para ver esto, el siguiente es un ejemplo de adicin simple en F#:
let number = 0 let result = number + 1

Cuando se ejecuta este cdigo en F# Interactive, se obtiene lo siguiente:


val number : int = 0 val result : int = 1

Probablemente deduzca por el trmino val que number y result son valores inmutables, no variables mutables. Puede ver esto mediante <-, el operador de asignacin de F#:
> number <- 15;; number <- 15;; ^^^^^^^^^^^^ stdin(3,1): error FS0027: This value is not mutable >

Dado que usted sabe que la programacin funcional se basa en la inmutabilidad, este error debe tener sentido. La palabra clave let se usa para crear enlaces inmutables entre nombres y valores. Los valores predeterminados slo son lo opuesto de aquello con lo que est familiarizado en los lenguajes imperativos:
let mutable myVariable = 0 myVariable <- 15

Inferencia de tipos y distincin de espacios en blanco


F# permite declarar variables y valores sin especificar su tipo, de modo que se podra suponer que F# es un lenguaje dinmico, pero no lo es. Es importante entender que F# es un lenguaje esttico. Afortunadamente, si usted es un desarrollador de C#, es muy probable que ya est familiarizado con inferencia de tipos bsica gracias a la palabra clave var:

// Here, the type is explictily given Dictionary<string, string> dictionary = new Dictionary<string, string>(); // but here, the type is inferred var dictionary = new Dictionary<string, string>();

Ambas lneas de cdigo C# crean nuevas variables que se escriben estticamente como Dictionary<string, string>, pero la palabra clave var indica al compilador que infiera el tipo de variable por usted. F# lleva este concepto al siguiente nivel. Por ejemplo, la siguiente es una funcin add en F#:
let add x y = x + y let four = add 2 2

No existe ni una sola anotacin de tipo en el cdigo anterior, pero F# Interactive revela los tipos estticos:
val add : int -> int -> int val four : int = 4

La inferencia de tipos es una manera en que F# reduce el ruido del cdigo, pero tenga en cuenta que no hay llaves ni palabras clave que denoten el cuerpo o el valor de retorno de la funcin add.

Efectos secundarios
Ahora usted sabe que la programacin funcional es diferente a la programacin imperativa, porque se basa en valores inmutables en lugar de variables mutables, pero este hecho no es muy til por s mismo. El siguiente paso es comprender los efectos secundarios. En la programacin imperativa, la salida de una funcin depende de su argumento de entrada y del estado actual del programa. En la programacin funcional, las funciones slo dependen de sus argumentos de entrada. En otras palabras, cuando se llama a una funcin ms de una vez con el mismo valor de entrada, siempre se obtiene el mismo valor de salida. Figura 1 Efectos secundarios de las variables mutables
public MemoryStream GetStream() { var stream = new MemoryStream(); var writer = new StreamWriter(stream); writer.WriteLine("line one"); writer.WriteLine("line two"); writer.WriteLine("line three"); writer.Flush(); stream.Position = 0; return stream; } [TestMethod]

public void CausingASideEffect() { using (var reader = new StreamReader(GetStream())) { var line1 = reader.ReadLine(); var line2 = reader.ReadLine(); Assert.AreNotEqual(line1, line2); } }

En la primera llamada a ReadLine, la secuencia se lee hasta que se encuentra una nueva lnea. Despus, ReadLine devuelve todo el texto a la nueva lnea. Entre esos pasos, se actualiza una variable mutable que representa la posicin de la secuencia. Ese es el efecto secundario. En la segunda llamada a ReadLine, el valor de la variable de posicin mutable ha cambiado, de modo que ReadLine devuelve un valor diferente. Ahora observemos una de las consecuencias ms significativas del uso de efectos secundarios. Primero, considere una clase PiggyBank simple y algunos mtodos para trabajar con ella (consulte la figura 2). Figura 2 PiggyBanks mutables
public class PiggyBank{ public PiggyBank(int coins){ Coins = coins; } public int Coins { get; set; } } private void DepositCoins(PiggyBank piggyBank){ piggyBank.Coins += 10; } private void BuyCandy(PiggyBank piggyBank){ if (piggyBank.Coins < 7) throw new ArgumentException( "Not enough money for candy!", "piggyBank"); piggyBank.Coins -= 7; }

Si tiene una piggy bank con 5 coins, puede llamar a DepositCoins antes de BuyCandy, pero si se invierte el orden se origina una excepcin:
// this works fine var piggyBank = new PiggyBank(5); DepositCoins(piggyBank); BuyCandy(piggyBank); // but this raises an ArgumentException var piggyBank = new PiggyBank(5); BuyCandy(piggyBank); DepositCoins(piggyBank);

La funcin BuyCandy y la funcin DepositCoins actualizan el estado de piggy bank a travs del uso de un efecto secundario. Por consiguiente, el comportamiento de cada funcin depende del estado de piggy bank. Dado que el nmero de coins es mutable, el orden en el que se ejecutan estas funciones es significativo. En otras palabras, existe una dependencia de intervalos implcita entre estos dos mtodos. Ahora hagamos que el nmero de coins sea de slo lectura para simular una estructura de datos inmutables. La figura 3 muestra que BuyCandy y DepositCoins ahora devuelven nuevos objetos PiggyBank en lugar de actualizar una PiggyBank existente. Figura 3 PiggyBanks inmutables
public class PiggyBank{ public PiggyBank(int coins){ Coins = coins; } public int Coins { get; private set; } } private PiggyBank DepositCoins(PiggyBank piggyBank){ return new PiggyBank(piggyBank.Coins + 10); } private PiggyBank BuyCandy(PiggyBank piggyBank){ if (piggyBank.Coins < 7) throw new ArgumentException( "Not enough money for candy!", "piggyBank"); return new PiggyBank(piggyBank.Coins - 7); }

Al igual que antes, si intenta llamar a BuyCandy antes de DepositCoins, recibir una excepcin de argumento:
// still raises an ArgumentException var piggyBank = new PiggyBank(5); BuyCandy(piggyBank); DepositCoins(piggyBank);

Pero ahora, aunque revierta el orden, obtendr el mismo resultado:


// now this raises an ArgumentException, var piggyBank = new PiggyBank(5); DepositCoins(piggyBank); BuyCandy(piggyBank); too!

Aqu, BuyCandy y DepositCoins slo dependen de su argumento de entrada dado que el nmero de coins es inmutable. Puede ejecutar las funciones en cualquier orden y el resultado ser el mismo. La dependencia de tiempo implcita desaparece. Sin embargo, dado que probablemente desee que BuyCandy tenga xito, debe hacer que el resultado de

BuyCandy dependa de la salida de DepositCoins. Debe hacer que la dependencia sea explcita:
var piggyBank = new PiggyBank(5); BuyCandy(DepositCoins(piggyBank));

Esta es una diferencia sutil con consecuencias de gran alcance. El estado mutable compartido y las dependencias implcitas son el origen de algunos de los errores ms complicados del cdigo imperativo y son la razn por la cual el subprocesamiento mltiple resulta tan difcil en los lenguajes imperativos En F#, el enfoque est en la evaluacin de valores de resultados de funciones y no en sus efectos secundarios. En lenguajes imperativos, es comn llamar a una funcin para que haga algo; en los lenguajes funcionales, se llama a las funciones para que devuelvan un resultado. Puede ver esto en F# al consultar la instruccin if:
let isEven x = if x % 2 = 0 then "yes" else "no"

Usted sabe que en F#, la ltima lnea de una funcin es el valor de retorno de sta, pero en este ejemplo, la ltima lnea de la funcin es la instruccin if. Esto no es un truco del compilador. En F#, incluso las instrucciones if estn diseadas para devolver valores:
let isEven2 x = let result = if x % 2 = 0 then "yes" else "no" result

El valor result es del tipo string y est asignado directamente a la instruccin if. Es similar a la forma en que el operador condicional funciona en C#:
string result = x % 2 == 0 ? "yes" : "no";

El operador condicional pone nfasis en el retorno de un valor por sobre la causa de un efecto secundario. Es un enfoque ms funcional. En contraste, la instruccin if de C# es ms imperativa, dado que no devuelve ningn resultado. Todo lo que puede hacer es ocasionar efectos secundarios. Figura 4 Uso de bucles foreach
IList<int> values = 0.Through(10).ToList(); // square a list IList<int> squaredValues = new List<int>();

foreach (int value in values) { squaredValues.Add(Square(value)); } // filter out the even values in a list IList<int> evens = new List<int>(); foreach(int value in values) { if (IsEven(value)) { evens.Add(value); } } // take the square of the even values IList<int> results = new List<int>(); foreach (int value in values) { if (IsEven(value)) { results.Add(Square(value)); } }

Los bucles foreach de este ejemplo son similares, pero cada cuerpo de bucle realiza una operacin levemente diferente. Los programadores imperativos tradicionalmente no han tenido problema con esta duplicacin de cdigo, dado que se considera cdigo idiomtico. Los programadores funcionales lo consideran desde otro punto de vista. En lugar de crear abstracciones como bucles foreach para ayudarse a pasar por las listas, usan funciones sin efectos secundarios:
let numbers = {0..10} let squaredValues = Seq.map Square numbers

Este cdigo F# tambin eleva al cuadrado una secuencia de nmeros, pero lo hace mediante una funcin de orden superior. Las funciones de orden superior son simplemente funciones que aceptan a otra funcin como argumento de entrada. En este caso, la funcin Seq.map acepta a la funcin Square como argumento. Aplica esta funcin a cada nmero de la secuencia numbers y devuelve la secuencia de nmeros elevados al cuadrado. Las funciones de orden superior son la razn por la que muchas personas afirman que la programacin funcional usa funciones como datos. Esto slo significa que las funciones se pueden usar como parmetros o se pueden asignar a un valor o variable una al igual que una int o string. En trminos de C#, es muy similar a los conceptos de delegados y expresiones lambda. Las funciones de orden superior son una de las tcnicas que hacen que la programacin funcional sea tan eficaz. Puede usar funciones de orden superior para aislar el cdigo duplicado dentro de bucles foreach y encapsularlo en funciones independientes y sin efectos secundarios. Cada una de estas funciones realiza una pequea operacin que el cdigo dentro del bucle foreach habra administrado. Gracias a que no tienen efectos

secundarios, es posible combinar estas funciones para crear cdigo ms legible y fcil de mantener, que logre lo mismo que los bucles foreach:
let squareOfEvens = numbers |> Seq.filter IsEven |> Seq.map Square

Lo nico confuso acerca de este cdigo puede ser el operador |>. Este operador se usa para que el cdigo sea ms legible, al permitir reordenar los argumentos en una funcin, de manera que el ltimo argumento sea el primero que usted lea. Su definicin es muy simple:
let (|>) x f = f x

Sin el operador |>, el cdigo squareOfEvens se vera as:


let squareOfEvens2 = Seq.map Square (Seq.filter IsEven numbers)

Si usa LINQ, el empleo de funciones de orden superior de esta forma debe parecer muy conocido. Esto se debe a que LINQ est profundamente enraizado en la programacin funcional. De hecho, es posible traducir el problema square of evens muy fcilmente a C# mediante mtodos de LINQ:
var squareOfEvens = numbers .Where(IsEven) .Select(Square);

Esto se traduce en la siguiente sintaxis de consulta de LINQ:


var squareOfEvens = from number in numbers where IsEven(number) select Square(number);

El uso de LINQ en cdigo C# o Visual Basic permite aprovechar parte de la eficacia de la programacin funcional diariamente. Es una excelente manera de aprender tcnicas de programacin funcional. Al comenzar a usar funciones de orden superior regularmente, tarde o temprano llegar a un punto en que desee crear una funcin pequea y muy especfica para pasar a una funcin de orden superior. Los programadores funcionales usan funciones lambda para resolver este problema. Las funciones lambda son simplemente funciones que se definen sin asignarles un nombre. Normalmente son pequeas y tienen un uso muy especfico. Por ejemplo, la siguiente es otra forma en la que se pueden elevar al cuadrado nmeros pares mediante una lambda:
let withLambdas = numbers

|> Seq.filter (fun x -> x % 2 = 0) |> Seq.map (fun x -> x * x)

La nica diferencia entre esto y el cdigo anterior para elevar al cuadrado nmeros pares y es que Square e IsEven se definen como lambdas. En F#, una funcin lambda se declara usando la palabra clave fun. Slo debe usar lambdas para declarar funciones con un solo uso, debido a que no se pueden usar fcilmente fuera del mbito en el que estn definidas. Por esta razn, Square e IsEven son opciones deficientes de funciones lambda, ya que sirven para muchas otras situaciones.

Ejemplo j#
J# COMPONENTE RadioButton y RadioButtonList Se utiliza para presentar al usuario un conjunto de opciones mutuamente excluyentes entre si, es decir, si el usuario selecciona un componente radio todos los demas componentes radioButton en la forma se desmarcan o deseleccionan solos, es por esta razon que decimos que radiobotones son mutuamente excluyentes. RADIOBUTTON: Codigo prog11.aspx
<FORM RUNAT=SERVER> SEXO:<BR> <ASP:RADIOBUTTON TEXT=MASCULINO ID=MASCULINO GROUPNAME=GRUPO1 RUNAT=SERVER /> <ASP:RADIOBUTTON TEXT=FEMENINO ID=FEMENINO GROUPNAME=GRUPO1 RUNAT=SERVER /><BR> <ASP:RADIOBUTTON TEXT=0-10 ID=DIEZ GROUPNAME=GRUPO2 RUNAT=SERVER /> <ASP:RADIOBUTTON TEXT=10-20 ID=VEINTE GROUPNAME=GRUPO2 RUNAT=SERVER /><BR> <ASP:BUTTON ONCLICK=EVENTO1 TEXT=OK RUNAT=SERVER /><BR> <ASP:LABEL ID=SEXO RUNAT=SERVER /><BR> <ASP:LABEL ID=EDAD RUNAT=SERVER /><BR> </FORM> <SCRIPT LANGUAGE=VJ# RUNAT=SERVER> void EVENTO1 (Object sender, EventArgs e)

{ if(MASCULINO.get_Checked()) SEXO.set_Text("MASCULINO"); if(FEMENINO.get_Checked()) SEXO.set_Text("FEMENINO"); if(DIEZ.get_Checked()) EDAD.set_Text("DE CERO A DIEZ"); if(VEINTE.get_Checked()) EDAD.set_Text("DE DIEZ A VEINTE"); } </script>

1.- Observar que tenemos dos grupos de radiobotones uno con GRUPNAME=GRUPO1 y otro con GROUPNAME=GRUPO2 sin embargo cada radiobuton tiene su propio valor o ID. 2.- La razon principal para esta situacion es que los radiobotones son mutuamente excluyentes entre si Y QUE SOLO UNO PUEDE ESTAR ENCENDIDO A LA VEZ por eso los agrupamos con la propiedad GROUPNAME para que html los pueda considerar como dos o mas grupos diferentes. 3.- Tambien pueden usar la propiedad checked=true para que aparezcan seleccionados al cargar el programa prog11.aspx 4.- Para programarlo usar la misma tecnica que se analizo con CHECKBOX es decir revisar la propiedad checked y un monton de if's ( un if por cada radiobutton). Corrida prog11.aspx

Como se observa checkbox son cajitas con una palomita y radiobutton son circulitos con un puntito negro. Pero su diferencia mas importante es que radiobtuton no permite que esten seleccionados dos o mas de ellos a la vez (dentro del mismo grupo o groupname). RADIOBUTTONLIST: Prog12.aspx
<FORM RUNAT=SERVER> SEXO:<BR> <ASP:RADIOBUTTONLIST ID=SEXO RUNAT=SERVER> <ASP:LISTITEM TEXT=MASCULINO RUNAT=SERVER /> <ASP:LISTITEM TEXT=FEMENINO RUNAT=SERVER /> <ASP:LISTITEM TEXT=NEUTRO RUNAT=SERVER /> </ASP:RADIOBUTTONLIST> <ASP:BUTTON ONCLICK=EVENTO1 TEXT=OK RUNAT=SERVER /><BR> <ASP:LABEL ID=SEX RUNAT=SERVER /><BR> </FORM> <SCRIPT LANGUAGE=VJ# RUNAT=SERVER> void EVENTO1 (Object sender, EventArgs e) { // como es un control similar a listbox, tambien puede usar prop selecteditem SEX.set_Text( SEXO.get_SelectedItem().get_Text()); } </script>

Igual que checkboxlist, es decir agregarle un ID al radiobutonlist, y un monton de listitem's y programarlo con la propiedad selecteditem que queda apuntando al radiobuton que seleciono el usuario. Corrida prog12.aspx

S-ar putea să vă placă și