sábado, 2 de mayo de 2015

C#
Introducción e información general



Historia

C# es el lenguaje orientado a objetos diseñado por Microsoft para su plataforma .NET.
Sus principales creadores son Scott Wiltamuth y Anders Hejlsberg, éste último también
Conocido por haber sido el diseñador del lenguaje Turbo Pascal y la herramienta RAD
Delphi. Apareció en: 2001. Sistema operativo: multiplataforma. C# combina los mejores
Elementos de múltiples lenguajes de amplia difusión como C++, Java, Visual Basic o
Delphi.
El nombre C Sharp fue inspirado por la notación musical, donde ♯ indica que la nota es
un semitono más alta, sugiriendo que C♯ es superior a C/C++. C♯, como parte de la
 plataforma.NET, está normalizado por ECMA desde diciembre de 2001.
Estructura básica
            Los programas en C# pueden constar de uno o varios archivos. Cada archivo puede
contener cero o varios espacios de nombres. Un espacio de nombres puede contener tipos como
clases, structs, interfaces, enumeraciones y delegados, además de otros espacios de nombres. A
continuación, se muestra el esqueleto de un programa en C# que contiene todos estos elementos.
using System;
namespace YourNamespace
{
    class YourClass
    {
    }

    struct YourStruct
    {
    }

    interface IYourInterface
    {
    }

    delegate int YourDelegate();

    enum YourEnum
    {
    }

    namespace YourNestedNamespace
    {
        struct YourStruct
        {
        }
    }

    class YourMainClass
    {
        static void Main(string[] args)
        {
            //Your program starts here...
        }
    }
}

Clase


 Una clase es una construcción que permite crear tipos personalizados propios mediante
la agrupación de variables de otros tipos, métodos y eventos. Una clase es como un plano. 
Define los datos y el comportamiento de un tipo. Si la clase no se declara como estática, el
código de cliente puede utilizarla mediante la creación de objetos o instancias que se asignan a
una variable. La variable permanece en memoria hasta que todas las referencias a ella están fuera
del ámbito. En ese momento, CLR la marca como apta para la recolección de elementos no
utilizados.
 Si la clase se declara como estática, solo existe una copia en memoria y el código de cliente solo
puede tener acceso a ella a través de la propia clase y no de una variable de instancia. 
Aunque se utilizan a veces de forma intercambiable, una clase y un objeto son cosas

diferentes. 

Una clase define un tipo de objeto, pero no es propiamente un objeto. Un objeto es

una entidad concreta basada en una clase y, a veces, se denomina instancia de una clase.

Los objetos se pueden crear con la palabra clave new seguida del nombre de la clase en la que se

basará el objeto, de la manera siguiente:

 

C#

Customer object1 = new Customer();


Cuando se crea una instancia de una clase, una referencia al objeto se vuelve a pasar al

programador. En el ejemplo anterior, object1 es una referencia a un objeto basado

en Customer. Esta referencia apunta al nuevo objeto, pero no contiene los datos del objeto. De

hecho, se puede crear una referencia a objeto sin crear un objeto:

C#

Customer object2;


No se recomienda crear este tipo de referencias que realmente no apuntan a un objeto existente,

ya que al intentar el acceso a un objeto a través de esa referencia se producirá un error en tiempo

de ejecución. No obstante, este tipo de referencia se puede crear para hacer referencia a un

objeto, ya sea creando un nuevo objeto o asignándola a un objeto existente, de la forma

siguiente:

C#

Customer object3 = new Customer();
Customer object4 = object3;


Este código crea dos referencias a objeto que se refieren al mismo objeto. Por

consiguiente, los cambios realizados en el objeto a través de object3 se reflejarán en los usos

posteriores de object4. Puesto que el acceso a los objetos basados en clases se realiza por

referencia, las clases se denominan tipos por referencia.

 




La herencia se realiza a través de una derivación, lo que significa que una clase se declara

utilizando una clase base de la cual hereda los datos y el comportamiento. Una clase base se

especifica anexando dos puntos y el nombre de la clase base a continuación del nombre de la

clase derivada, del modo siguiente:
C#         

public class Manager : Employee
{
    // Employee fields, properties, methods and events are inherited
    // New Manager fields, properties, methods and events go here...
}


Cuando una clase declara una clase base, hereda todos los miembros de la clase base excepto los

 constructores.
A diferencia de C++, una clase en C# solo puede heredar directamente de una clase base. Sin

embargo, dado que una clase base puede heredar de otra clase, una clase puede heredar

indirectamente de varias clases base. Además, una clase puede implementar directamente más de

una interfaz. Para obtener más información, vea Interfaces (Guía de programación de C#).

Una clase se puede declarar como abstracta. Una clase abstracta contiene métodos abstractos que

incluyen una definición de firma pero ninguna implementación. No se pueden crear instancias de

 las clases abstractas. Solo se pueden utilizar a través de clases derivadas que implementan los

métodos abstractos. Por el contrario, una clasesellada no permite que otras clases deriven de


Las definiciones de clase se pueden dividir entre archivos de código fuente diferentes. Para



En el ejemplo siguiente, se define una clase pública que contiene un campo único, un método y

un método especial denominado constructor. Para obtener más información, vea Constructores     
(Guía de programación de C#). Luego se crean instancias de la clase con la palabra clave new.

C#

public class Person
{
    // Field
    public string name;

    // Constructor that takes no arguments.
    public Person()
    {
        name = "unknown";
    }

    // Constructor that takes one argument.
    public Person(string nm)
    {
        name = nm;
    }

    // Method
    public void SetName(string newName)
    {
        name = newName;
    }
}
class TestPerson
{
    static void Main()
    {
        // Call the constructor that has no parameters.
        Person person1 = new Person();
        Console.WriteLine(person1.name);

        person1.SetName("John Smith");
        Console.WriteLine(person1.name);

        // Call the constructor that has one parameter.
        Person person2 = new Person("Sarah Jones");
        Console.WriteLine(person2.name);

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
// Output:
// unknown
// John Smith
// Sarah Jones

Librerías

Comandos consola


tienen las clases de “System.Diagnostics” y en particular la clase “Process”, que permite realizar

llamadas a Procesos externos.

Para este ejemplo voy a crear una aplicación muy simple llamada CMD Executer que su única

función es ejecutar comandos CMD.

Primero vamos a crear una clase estática llamada “ExecuteCommand” que recibe como

parámetro un comando como cadena de texto:

        static void ExecuteCommand(string _Command)
        {
            //Indicamos que deseamos inicializar el proceso cmd.exe junto a un comando de arranque. 
            //(/C, le indicamos al proceso cmd que deseamos que cuando termine la tarea asignada se cierre el proceso).
            //Para mas informacion consulte la ayuda de la consola con cmd.exe /? 
            System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd""/c " + _Command);
            // Indicamos que la salida del proceso se redireccione en un Stream
            procStartInfo.RedirectStandardOutput = true;
            procStartInfo.UseShellExecute = false;
            //Indica que el proceso no despliegue una pantalla negra (El proceso se ejecuta en background)
            procStartInfo.CreateNoWindow = false;
            //Inicializa el proceso
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = procStartInfo;
            proc.Start();
            //Consigue la salida de la Consola(Stream) y devuelve una cadena de texto
            string result = proc.StandardOutput.ReadToEnd();
            //Muestra en pantalla la salida del Comando
            Console.WriteLine(result);
        }

Nuestro siguiente paso, para que parezca una consola verdadera es crear un ciclo while infinito, que se detenga cuando ingresemos el comando “Salir”:
        static void Main(string[] args)
        {
            string command = "dir";
            Console.WriteLine("CMD Executer V.0.1");
            Console.WriteLine("Last Release 05 - Febraury - 2012");
 
            while (true)
            {
                Console.Write("#:");
                command = Console.ReadLine();
                if (command == "Salir" || command == "salir")
                {
                    break;
                }
                ExecuteCommand(command);
            }
        }
 
Captura y Lectura de datos
 
Las propiedades proporcionan la comodidad de utilizar miembros de datos públicos sin los

riesgos que implica el acceso no protegido y sin control ni comprobación a los datos de un

objeto. Esto se logra a través de los descriptores de acceso: métodos especiales que asignan y

recuperan los valores del miembro de datos subyacente. El descriptor de acceso set permite

asignar los miembros de datos y el descriptor de acceso get recupera los valores de los miembros

de datos.
Este ejemplo muestra una clase Person con dos propiedades: Name (cadena)

y Age (entero). Ambas propiedades proporcionan descriptores de acceso get y set, por lo que se

consideran propiedades de lectura y escritura.

Ejemplo

C#
 
class Person
{
    private string name = "N/A";
    private int age = 0;
 
    // Declare a Name property of type string:
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
        }
    }
 
    // Declare an Age property of type int:
    public int Age
    {
        get
        {
            return age;
        }
 
        set
        {
            age = value;
        }
    }
 
    public override string ToString()
    {
        return "Name = " + Name + ", Age = " + Age;
    }
}
 
class TestPerson
{
    static void Main()
    {
        // Create a new Person object:
        Person person = new Person();
 
        // Print out the name and the age associated with the person:
        Console.WriteLine("Person details - {0}", person);
 
        // Set some values on the person object:
        person.Name = "Joe";
        person.Age = 99;
        Console.WriteLine("Person details - {0}", person);
 
        // Increment the Age property:
        person.Age += 1;
        Console.WriteLine("Person details - {0}", person);
 
        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Person details - Name = N/A, Age = 0
    Person details - Name = Joe, Age = 99
    Person details - Name = Joe, Age = 100
*/
 

Estructuras repetitivas

Hemos visto cómo comprobar condiciones, pero no cómo hacer que una cierta parte de un programa se repita un cierto número de veces o mientras se cumpla una condición (lo que llamaremos un "bucle"). En C# tenemos varias formas de conseguirlo.

While

Si queremos hacer que una sección de nuestro programa se repita mientras se cumpla una cierta condición, usaremos la orden "while". Esta orden tiene dos formatos distintos, según comprobemos la condición al principio o al final.
En el primer caso, su sintaxis es:
   while (condición)
     sentencia;
Es decir, la sentencia se repetirá mientras la condición sea cierta. Si la condición es falsa ya desde un principio, la sentencia no se ejecuta nunca. Si queremos que se repita más de una sentencia, basta agruparlas entre { y }.
Un ejemplo que nos diga si cada número que tecleemos es positivo o negativo, y que pare cuando tecleemos el número 0, podría ser:
/*---------------------------*/
/*  Ejemplo en C# nº 22:     */
/*  ejemplo22.cs             */
/*                           */
/*  La orden "while"         */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo22
{
  public static void Main()
  {
    int numero;
 
    Console.Write("Teclea un número (0 para salir): ");
    numero = Convert.ToInt32(Console.ReadLine());
    while (numero != 0)
    {
      if (numero > 0) Console.WriteLine("Es positivo");
        else Console.WriteLine("Es negativo");
      Console.WriteLine("Teclea otro número (0 para salir): ");
      numero = Convert.ToInt32(Console.ReadLine());
    }
  }
}
 
En este ejemplo, si se introduce 0 la primera vez, la condición es falsa y ni siquiera se entra al bloque del "while", terminando el programa inmediatamente.

Do while

Este es el otro formato que puede tener la orden "while": la condición se comprueba al final. El punto en que comienza a repetirse se indica con la orden "do", así:
   do 
     sentencia;
   while (condición);
Al igual que en el caso anterior, si queremos que se repitan varias órdenes (es lo habitual), deberemos encerrarlas entre llaves.
Como ejemplo, vamos a ver cómo sería el típico programa que nos pide una clave de acceso y no nos deja entrar hasta que tecleemos la clave correcta:
/*---------------------------*/
/*  Ejemplo en C# nº 23:     */
/*  ejemplo23.cs             */
/*                           */
/*  La orden "do..while"     */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo23
{
  public static void Main()
  {
 
    int valida = 711;
    int clave;
 
    do
    {
      Console.Write("Introduzca su clave numérica: ");
      clave = Convert.ToInt32(Console.ReadLine());
      if (clave != valida) Console.WriteLine("No válida!\n");
    }
    while (clave != valida);
    Console.WriteLine("Aceptada.\n");
 
  }
}
 
En este caso, se comprueba la condición al final, de modo que se nos preguntará la clave al menos una vez. Mientras que la respuesta que demos no sea la correcta, se nos vuelve a preguntar. Finalmente, cuando tecleamos la clave correcta, el ordenador escribe "Aceptada" y termina el programa.
Si preferimos que la clave sea un texto en vez de un número, los cambios al programa son mínimos:
/*---------------------------*/
/*  Ejemplo en C# nº 24:     */
/*  ejemplo24.cs             */
/*                           */
/*  La orden "do..while" (2) */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo24
{
  public static void Main()
  {
 
    string valida = "secreto";
    string clave;
 
    do
    {
      Console.Write("Introduzca su clave: ");
      clave = Console.ReadLine();
      if (clave != valida) Console.WriteLine("No válida!\n");
    }
    while (clave != valida);
    Console.WriteLine("Aceptada.\n");
 
  }
}
 

For

Ésta es la orden que usaremos habitualmente para crear partes del programa que se repitan un cierto número de veces. El formato de "for" es:
   for (valorInicial; CondiciónRepetición; Incremento)
     Sentencia;
Así, para contar del 1 al 10, tendríamos 1 como valor inicial, <=10 como condición de repetición, y el incremento sería de 1 en 1. Por tanto, el programa quedaría:
/*---------------------------*/
/*  Ejemplo en C# nº 25:     */
/*  ejemplo25.cs             */
/*                           */
/*  Uso básico de "for"      */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo25
{
  public static void Main()
  {
 
    int contador;
 
    for (contador=1; contador<=10; contador++)
      Console.Write("{0} ", contador);
 
  }
}
 
Recordemos que "contador++" es una forma abreviada de escribir "contador=contador+1", de modo que en este ejemplo aumentamos la variable de uno en uno.
En un "for", realmente, la parte que hemos llamado "Incremento" no tiene por qué incrementar la variable, aunque ése es su uso más habitual. Es simplemente una orden que se ejecuta cuando se termine la "Sentencia" y antes de volver a comprobar si todavía se cumple la condición de repetición.
Por eso, si escribimos la siguiente línea:
     for (contador=1; contador<=10; )
la variable "contador" no se incrementa nunca, por lo que nunca se cumplirá la condición de salida: nos quedamos encerrados dando vueltas dentro de la orden que siga al "for".
Un caso todavía más exagerado de algo a lo que se entra y de lo que no se sale sería la siguiente orden:
     for ( ; ; )
Los bucles "for" se pueden anidar (incluir uno dentro de otro), de modo que podríamos escribir las tablas de multiplicar del 1 al 5 con:
/*---------------------------*/
/*  Ejemplo en C# nº 26:     */
/*  ejemplo26.cs             */
/*                           */
/*  "for" anidados           */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo26
{
  public static void Main()
  {
 
    int tabla, numero;
 
    for (tabla=1; tabla<=5; tabla++)
      for (numero=1; numero<=10; numero++)
        Console.WriteLine("{0} por {1} es {2}", tabla, numero,
          tabla*numero);
 
  }
}
 
En estos ejemplos que hemos visto, después de "for" había una única sentencia. Si queremos que se hagan varias cosas, basta definirlas como un bloque (una sentencia compuesta) encerrándolas entre llaves. Por ejemplo, si queremos mejorar el ejemplo anterior haciendo que deje una línea en blanco entre tabla y tabla, sería:
/*---------------------------*/
/*  Ejemplo en C# nº 27:     */
/*  ejemplo27.cs             */
/*                           */
/*  "for" anidados (2)       */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo27
{
  public static void Main()
  {
 
    int tabla, numero;
 
    for (tabla=1; tabla<=5; tabla++) 
    {
      for (numero=1; numero<=10; numero++) 
        Console.WriteLine("{0} por {1} es {2}", tabla, numero,
          tabla*numero);
      Console.WriteLine();
    }
 
  }
}
 
Para "contar" no necesariamente hay que usar números. Por ejemplo, podemos contar con letras así:
/*---------------------------*/
/*  Ejemplo en C# nº 28:     */
/*  ejemplo28.cs             */
/*                           */
/*  "for" que usa "char"     */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo28
{
  public static void Main()
  {
 
    char letra;
 
    for (letra='a'; letra<='z'; letra++)
      Console.Write("{0} ", letra);
 
  }
}
 
En este caso, empezamos en la "a" y terminamos en la "z", aumentando de uno en uno.
Si queremos contar de forma decreciente, o de dos en dos, o como nos interese, basta indicarlo en la condición de finalización del "for" y en la parte que lo incrementa:
/*---------------------------*/
/*  Ejemplo en C# nº 29:     */
/*  ejemplo29.cs             */
/*                           */
/*  "for" que descuenta      */
/*                           */
/*  Introduccion a C#,       */
/*    Nacho Cabanes          */
/*---------------------------*/
 
using System;
 
public class Ejemplo29
{
  public static void Main()
  {
 
    char letra;
 
    for (letra='z'; letra>='a'; letra--)
      Console.Write("{0} ", letra);
 
  }
}
 
 
Estructura condicional
 
Una instrucción if identifica que sentencia se tiene que ejecutar en función del valor de una expresión Boolean. En el ejemplo siguiente, la variable Booleanresult se establece en true y, a continuación, se comprueba en la instrucción if. La salida es The condition is true.

C#
 
bool condition = true;
 
if (condition)
{
    Console.WriteLine("The variable is set to true.");
}
else
{
    Console.WriteLine("The variable is set to false.");
}
 
 
Puede ejecutar los ejemplos de este tema colocándolos en el método de Main de una aplicación de consola.
Una instrucción if en C# puede tomar dos formas, como se muestra en el ejemplo siguiente.

C#
 
// if-else statement
if (condition)
{
    then-statement;
}
else
{
    else-statement;
}
// Next statement in the program.
 
 
// if statement without an else
if (condition)
{
    then-statement;
}
// Next statement in the program.
 
En una instrucción if-else, si la condición se evalúa como true, se ejecuta la sentencia then-statement. Si condition es false, else-statement ejecuta. Dado que la condición (condition) no puede ser simultáneamente verdadera (true) y falsa (false), las sentencias then-statement y else-statement de una instrucción if-else nunca pueden ejecutarse simultáneamente. Después de then-statement o de las ejecuciones de else-statement, el control se transfiere a la instrucción siguiente después de la instrucción de if.
En una instrucción de if que no incluya una instrucción de else, si condition es true, then-statement ejecuta. Si condition es false, el control se transfiere a la instrucción siguiente después de la instrucción de if.
then-statement y else-statement pueden constar de una sola instrucción o varias instrucciones que se agrega entre llaves ({}). Para una sola instrucción, las llaves son opcionales pero recomendados.
La instrucción o instrucciones en then-statement y else-statement puede ser de clase, incluso otra instrucción de if anidada dentro de la instrucción original de if. En instrucciones anidadas de if, cada cláusula de else pertenece a if último que no tiene else correspondiente. En el ejemplo siguiente, Result1 aparece si m > 10 y n > 20 se evalúan como true. Si m > 10 es true pero n > 20 es false, Result2 aparece.

C#
 
// Try with m = 12 and then with m = 8.
int m = 12;
int n = 18;
 
if (m > 10)
    if (n > 20)
    {
        Console.WriteLine("Result1");
    }
    else
    {
        Console.WriteLine("Result2");
    }
 
 
Si, en su lugar, se desea que Result2 aparezca cuando (m > 10) es false, puede especificar que la asociación mediante las llaves para establecer el inicio y el final de la instrucción anidada de if, como se muestra en el ejemplo siguiente.

C#
 
// Try with m = 12 and then with m = 8.
if (m > 10)
{
    if (n > 20)
        Console.WriteLine("Result1");
}
else
{
    Console.WriteLine("Result2");
}
 
 
Result2 aparece si la condición (m > 10) evalúa en false.

Ejemplo


En el ejemplo siguiente, se escribe un carácter de teclado, y el programa utiliza una instrucción anidada de if para determinar si el carácter de entrada es un carácter alfabético.Si el carácter de entrada es un carácter alfabético, el programa comprueba si el carácter se introdujo en minúsculas o en mayúsculas. Aparecerá un mensaje para cada caso.

C#
 
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("The character isn't an alphabetic character.");
}
 
//Sample Output:
 
//Enter a character: 2
//The character isn't an alphabetic character.
 
//Enter a character: A
//The character is uppercase.
 
//Enter a character: h
//The character is lowercase.
 
 
También puede anidar una instrucción de if dentro de un bloque else, como el código parcial siguiente. Las instrucciones de if de los nidos de ejemplo desde dos bloques otros y una continuación bloqueada. Los comentarios especifican qué condiciones son true o false en cada bloque.

C#
 
// Change the values of these variables to test the results.
bool Condition1 = true;
bool Condition2 = true;
bool Condition3 = true;
bool Condition4 = true;
 
if (Condition1)
{
    // Condition1 is true.
}
else if (Condition2)
{
    // Condition1 is false and Condition2 is true.
}
else if (Condition3)
{
    if (Condition4)
    {
        // Condition1 and Condition2 are false. Condition3 and Condition4 are true.
    }
    else
    {
        // Condition1, Condition2, and Condition4 are false. Condition3 is true.
    }
}
else
{
    // Condition1, Condition2, and Condition3 are false.
}
 
 
El ejemplo siguiente determina si un carácter de entrada es una minúscula, una letra mayúscula, o un número. Si las tres condiciones son false, el carácter no es un carácter alfanumérico. El ejemplo muestra un mensaje para cada caso.

C#
 
Console.Write("Enter a character: ");
char ch = (char)Console.Read();
 
if (Char.IsUpper(ch))
{
    Console.WriteLine("The character is an uppercase letter.");
}
else if (Char.IsLower(ch))
{
    Console.WriteLine("The character is a lowercase letter.");
}
else if (Char.IsDigit(ch))
{
    Console.WriteLine("The character is a number.");
}
else
{
    Console.WriteLine("The character is not alphanumeric.");
}
 
//Sample Input and Output:
//Enter a character: E
//The character is an uppercase letter.
 
//Enter a character: e
//The character is a lowercase letter.
 
//Enter a character: 4
//The character is a number.
 
//Enter a character: =
//The character is not alphanumeric.
 
 
Igual que una instrucción del bloque else o el bloque then puede ser cualquier instrucción válida, puede utilizar cualquier expresión booleana válida para la condición. Puede usar operadores lógicos como &&, y, ||, |y ! para crear condiciones compuestas. El código siguiente muestra ejemplos.

C#
// NOT
bool result = true;
if (!result)
{
    Console.WriteLine("The condition is true (result is false).");
}
else
{
    Console.WriteLine("The condition is false (result is true).");
}
 
// Short-circuit AND
int m = 9;
int n = 7;
int p = 5;
if (m >= n && m >= p)
{
    Console.WriteLine("Nothing is larger than m.");
}
 
// AND and NOT
if (m >= n && !(p > m))
{
    Console.WriteLine("Nothing is larger than m.");
}
 
// Short-circuit OR
if (m > n || m > p)
{
    Console.WriteLine("m isn't the smallest.");
}
 
// NOT and OR
m = 4;
if (!(m >= n || m >= p))
{
    Console.WriteLine("Now m is the smallest.");
}
// Output:
// The condition is false (result is true).
// Nothing is larger than m.
// Nothing is larger than m.
// m isn't the smallest.
// Now m is the smallest.
 
 

Matrices en general

En las matrices de C#, los índices empiezan en cero. Las matrices de C# funcionan de forma similar a como lo hacen en la mayoría de los lenguajes populares; existen, sin embargo, algunas diferencias que se deben conocer.
Cuando se declara una matriz, los corchetes ([]) deben ir después del tipo, no después del identificador. Colocar los corchetes después del identificador no es sintácticamente válido en

C#.
int[] table; // not int table[];  
 
Otro detalle es que el tamaño de la matriz no forma parte de su tipo, como ocurre en el lenguaje C. Esto permite declarar una matriz y asignarle cualquier matriz de objetos int, independientemente de la longitud de la matriz.

int[] numbers; // declare numbers as an int array of any size
numbers = new int[10];  // numbers is a 10-element array
numbers = new int[20];  // now it's a 20-element array
 

Declarar matrices


C# admite matrices de una dimensión, matrices multidimensionales (matrices rectangulares) y matrices de matrices (matrices escalonadas). El siguiente ejemplo muestra cómo declarar diferentes tipos de matrices:
Matrices unidimensionales:
int[] numbers;
 
Matrices multidimensionales:
string[,] names;
 
Matrices de matrices (escalonadas):
byte[][] scores;
 
La declaración de matrices (como se muestra arriba) no crea realmente las matrices. En C#, las matrices son objetos (se explica más adelante en este tutorial) cuyas instancias deben crearse. Los siguientes ejemplos muestran cómo crear matrices:
Matrices unidimensionales:

int[] numbers = new int[5];
Matrices multidimensionales:
string[,] names = new string[5,4];
Matrices de matrices (escalonadas):
byte[][] scores = new byte[5][];
for (int x = 0; x < scores.Length; x++) 
{
   scores[x] = new byte[4];
}
 
También se pueden utilizar matrices más grandes. Por ejemplo, se puede utilizar una matriz rectangular de tres dimensiones:
int[,,] buttons = new int[4,5,3];
 
Incluso, se pueden combinar matrices rectangulares y escalonadas. Por ejemplo, el siguiente código declara una matriz unidimensional que contiene matrices tridimensionales de matrices bidimensionales de tipo int:
int[][,,][,] numbers;
 

Ejemplo

El siguiente es un programa completo en C# que declara y crea instancias de las matrices comentadas anteriormente.

// arrays.cs
using System;
class DeclareArraysSample
{
    public static void Main()
    {
        // Single-dimensional array
        int[] numbers = new int[5];
 
        // Multidimensional array
        string[,] names = new string[5,4];
 
        // Array-of-arrays (jagged array)
        byte[][] scores = new byte[5][];
 
        // Create the jagged array
        for (int i = 0; i < scores.Length; i++)
        {
            scores[i] = new byte[i+3];
        }
 
        // Print length of each row
        for (int i = 0; i < scores.Length; i++)
        {
            Console.WriteLine("Length of row {0} is {1}", i, scores[i].Length);
        }
    }
}

Resultado

Length of row 0 is 3
Length of row 1 is 4
Length of row 2 is 5
Length of row 3 is 6
Length of row 4 is 7
 

Inicializar matrices

C# proporciona métodos simples y sencillos para inicializar matrices en el momento de la declaración encerrando los valores iniciales entre llaves ({}). Los siguientes ejemplos muestran diferentes modos de inicializar diferentes tipos de matrices.
Nota   Si no inicializa una matriz en el momento de la declaración, sus miembros se inicializan automáticamente con el valor inicial predeterminado para el tipo de matriz. Además, si declara la matriz como campo de un tipo, se establecerá con el valor predeterminado null cuando cree la instancia del tipo.

Matrices unidimensionales

int[] numbers = new int[5] {1, 2, 3, 4, 5};
string[] names = new string[3] {"Matt", "Joanne", "Robert"};
 
El tamaño de la matriz se puede omitir, como se indica a continuación:
int[] numbers = new int[] {1, 2, 3, 4, 5};
string[] names = new string[] {"Matt", "Joanne", "Robert"};
 
También se puede omitir el operador new si se utiliza un inicializador como el siguiente:
int[] numbers = {1, 2, 3, 4, 5};
string[] names = {"Matt", "Joanne", "Robert"};
 

Matrices multidimensionales

int[,] numbers = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} };
string[,] siblings = new string[2, 2] { {"Mike","Amy"}, {"Mary","Albert"} };
 
El tamaño de la matriz se puede omitir, como se indica a continuación:
int[,] numbers = new int[,] { {1, 2}, {3, 4}, {5, 6} };
string[,] siblings = new string[,] { {"Mike","Amy"}, {"Mary","Albert"} };
 
También se puede omitir el operador new si se utiliza un inicializador como el siguiente:
int[,] numbers = { {1, 2}, {3, 4}, {5, 6} };
string[,] siblings = { {"Mike", "Amy"}, {"Mary", "Albert"} };
 

Matriz escalonada (matriz de matrices)

Las matrices escalonadas se pueden inicializar como en el siguiente ejemplo:
int[][] numbers = new int[2][] { new int[] {2,3,4}, new int[] {5,6,7,8,9} };
 
El tamaño de la primera matriz se puede omitir, como se indica a continuación:
int[][] numbers = new int[][] { new int[] {2,3,4}, new int[] {5,6,7,8,9} };
O bien
int[][] numbers = { new int[] {2,3,4}, new int[] {5,6,7,8,9} };
 
Observe que no existe sintaxis de inicialización para los elementos de una matriz escalonada.

Acceso a miembros de matrices

El acceso a los miembros de una matriz es sencillo y similar al de los miembros de una matriz de C o C++. Por ejemplo, el siguiente código crea una matriz denominada numbersy, a continuación, asigna un 5 al quinto elemento de la matriz:
int[] numbers = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
numbers[4] = 5;
 
El siguiente código declara una matriz multidimensional y asigna el valor 5 al miembro ubicado en [1, 1]:
int[,] numbers = { {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10} };
numbers[1, 1] = 5;
 
La siguiente es una declaración de una matriz escalonada de una sola dimensión que contiene dos elementos. El primer elemento es una matriz de dos enteros, mientras que el segundo es una matriz de tres enteros:
int[][] numbers = new int[][] { new int[] {1, 2}, new int[] {3, 4, 5}
};
 
La siguiente instrucción asigna 58 al primer elemento de la primera matriz y 667 al segundo elemento de la segunda matriz:
numbers[0][0] = 58;
numbers[1][1] = 667;
 

Las matrices son objetos

En C#, las matrices son realmente objetos. System.Array es el tipo base abstracto de todos los tipos de matrices. Las propiedades y otros miembros de la clase System.Array se pueden utilizar cuando sea necesario. Un ejemplo de esto sería utilizar la propiedad Length para obtener la longitud de una matriz. El siguiente código asigna la longitud de la matriz numbers, que es 5, a una variable denominada LengthOfNumbers:
int[] numbers = {1, 2, 3, 4, 5};
int LengthOfNumbers = numbers.Length;
 
La clase System.Array proporciona muchos otros métodos y propiedades útiles, como métodos para ordenar, buscar y copiar matrices.

Usar foreach con matrices

C# dispone de la instrucción foreach. Esta instrucción proporciona un modo simple y limpio de iterar en los elementos de una matriz. Por ejemplo, el siguiente código crea una matriz denominada numbers y la recorre mediante la instrucción foreach:
int[] numbers = {4, 5, 6, 1, 2, 3, -2, -1, 0};
foreach (int i in numbers)
{
   System.Console.WriteLine(i);
}
Con matrices multidimensionales, se puede utilizar el mismo método para recorrer los elementos, por ejemplo:
int[,] numbers = new int[3, 2] {{9, 99}, {3, 33}, {5, 55}};
foreach(int i in numbers)
{
   Console.Write("{0} ", i);
}
El resultado de este ejemplo es:
9 99 3 33 5 55
 
Conexion a base de datos
 
La conexión a un origen de datos se realiza fácilmente con Visual C# Express. Puede utilizar herramientas visuales para buscar una base de datos y agregar una copia local al proyecto. Al instalar SQL Server Compact 3.5 con Visual C# Express, podrá utilizar una base de datos de ejemplo denominada Northwind.sdf. Puede conectarse a la base de datos Northwind mediante la ventana Orígenes de datos.

Para agregar una conexión a la base de datos Northwind

1.      En el menú Archivo, haga clic en Nuevo proyecto.
2.      En el cuadro de diálogo Nuevo proyecto, haga clic en Aplicación para Windows y luego en Aceptar.
Se abrirá un nuevo proyecto de formularios Windows Forms.
3.      En el menú Datos, haga clic en Agregar nuevo origen de datos.
Se abrirá el Asistente para la configuración de orígenes de datos.
4.      Haga clic en Base de datos y, a continuación, en Siguiente.
5.      Haga clic en Nueva conexión.
Se abrirá el cuadro de diálogo Agregar conexión.
6.      En el cuadro de diálogo Agregar conexión, si el Origen de datos no es Microsoft SQL Server Compact 3.5 (proveedor de datos de .NET Framework para Microsoft SQL Server Compact 3.5), haga clic en Cambiar y seleccione Microsoft SQL Server Compact 3.5 en el cuadro de diálogo Cambiar origen de datos. Haga clic en Aceptar.
7.      Haga clic en el botón Examinar y busque la base de datos Northwind.sdf.
La ubicación predeterminada es unidad:\Archivos de programa\Microsoft SQL Server Compact Edition\v 3.5\Samples.
8.      Haga clic en Probar conexión para comprobar que la conexión es satisfactoria y, a continuación, haga clic en Aceptar para cerrar el cuadro de diálogo.
9.      Haga clic en Aceptar para cerrar el cuadro de diálogo y, a continuación, en el Asistente para la configuración de orígenes de datos, haga clic en Siguiente. Si se le pide copiar el archivo de datos en su proyecto, haga clic en .
10.  En la página siguiente del asistente, seleccione la casilla Sí, guardar la conexión como y, a continuación, haga clic en Siguiente.
11.  En la página Elija los objetos de base de datos, expanda Tablas.
12.  Active la casilla para Productos y Detalles del pedido y, a continuación, haga clic en Finalizar.
Se agrega un archivo de base de datos local al proyecto. Observe que se ha agregado un objeto NorthwindDataSet a la ventana Orígenes de datos.
13.  En el Explorador de soluciones, seleccione Northwind.sdf y asegúrese de que la propiedad Copiar en el directorio de resultados presenta el valor Copiar si es posterior.
14.  En el menú Archivo, haga clic en Guardar todo para guardar el proyecto.
Conexión a SQL server

Puede conectar a una base de datos de Microsoft SQL Server utilizando el control SqlDataSource. Para ello, necesita una cadena de conexión y derechos de acceso a una base de datos de SQL Server. A continuación, puede utilizar el control SqlDataSource para proporcionar los datos a cualquier control enlazado a datos que admita la propiedadDataSourceID, por ejemplo, el control GridView.

Para configurar una cadena de conexión de SQL Server en el archivo Web.config


1.      Abra el archivo Web.config en el directorio raíz de su aplicación ASP.NET. Si no dispone de un archivo Web.config, cree uno.
2.      En el elemento Configuration, agregue un elemento ConnectionStrings si no existe ninguno.
3.      Cree un elemento add como elemento secundario del elemento ConnectionStrings, y defina los atributos siguientes:
o    name   Establezca el valor en el nombre que desea utilizar para hacer referencia a la cadena de conexión, como en el ejemplo siguiente.
o    name="CustomerDataConnectionString"
o    connectionString   Asigne una cadena de conexión con la ubicación de su SQL Server e información de autenticación, si existe. La cadena de conexión podría parecerse a la siguiente:
o    connectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind"
o    providerName   Asigne el valor "System.Data.SqlClient", que especifica que ASP.NET debe utilizar el proveedor de ADO.NET System.Data.SqlClient al realizar una conexión con esta cadena de conexión.
La configuración de la cadena de conexión será similar a la siguiente:

<connectionStrings>
  <add name="CustomerDataConnectionString" 
    connectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind"
    providerName="System.Data.SqlClient" />
</connectionStrings>
 
4.      Guarde el archivo Web.config y ciérrelo.

Para hacer referencia a la cadena de conexión de SQL Server desde un control SqlDataSource

1.      Agregue un control SqlDataSource en la página en la que desea conectar a la base de datos de SQL Server.
2.      En el control SqlDataSource, establezca las siguientes propiedades:
o    SelectCommand   Establezca el valor en una instrucción Select de SQL para recuperar los datos, como en el ejemplo siguiente ejemplo:
o    SelectCommand="Select CustomerID, CompanyName From Customers"
o    ConnectionString   Establezca el nombre de la cadena de conexión que ha creado en el archivo Web.config con el formato <%$ ConnectionStrings: connection string name %>.
En el ejemplo siguiente se muestra un control SqlDataSource configurado para establecer una conexión con una base de datos de SQL Server.

<asp:SqlDataSource 
  ID="SqlDataSource1"
  runat="server" 
  ConnectionString="<%$ ConnectionStrings:CustomerDataConnectionString %>"
  SelectCommand="SELECT CustomerID, CompanyName FROM Customers"   />



Lista de referencias