Comparte esta página

Aprende X en Y minutos

Donde X=C#

C# es un lenguaje orientado a objetos elegante y de tipado seguro que permite a los desarrolladores construir una variedad de aplicaciones seguras y robustas que se ejecutan en el Framework .NET.

Lee más aquí.

// Los comentarios de una sola línea comienzan con //
/*
Los comentarios de múltiples líneas son de esta manera
*/
/// <summary>
/// Este es un comentario de documentación XML
/// </summary>

// Especifica el espacio de nombres que estará usando la aplicación
using System;
using System.Collections.Generic;


// Define un ambito para organizar el código en "paquetes"
namespace Learning
{
    // Cada archivo .cs debe contener al menos una clase con el mismo nombre que el archivo
    // Se permite colocar cualquier nombre, pero no deberías por cuestiones de consistencia.
    public class LearnCSharp
    {
        // Una aplicación de consola debe tener un método main como punto de entrada
        public static void Main(string[] args)
        {
            // Usa Console.WriteLine para imprimir líneas
            Console.WriteLine("Hello World");
            Console.WriteLine(
                "Integer: " + 10 +
                " Double: " + 3.14 +
                " Boolean: " + true);

            // Para imprimir sin una nueva línea, usa Console.Write
            Console.Write("Hello ");
            Console.Write("World");


            ///////////////////////////////////////////////////
            // Variables y Tipos
            //
            // Declara una variable usando <tipo> <nombre>
            ///////////////////////////////////////////////////

            // Sbyte - Entero de 8 bits con signo
            // (-128 <= sbyte <= 127)
            sbyte fooSbyte = 100;

            // Byte - Entero de 8 bits sin signo
            // (0 <= byte <= 255)
            byte fooByte = 100;

            // Short - Entero de 16 bits con signo
            // (-32,768 <= short <= 32,767)
            short fooShort = 10000;

            // Ushort - Entero de 16 bits sin signo
            // (0 <= ushort <= 65,535)
            ushort fooUshort = 10000;

            // Integer - Entero de 32 bits con signo
            // (-2,147,483,648 <= int <= 2,147,483,647)
            int fooInt = 1;

            // Uinteger - Entero de 32 bits sin signo
            // (0 <= uint <= 4,294,967,295)
            uint fooUint = 1;

            // Long - Entero de 64 bits con signo
            // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
            long fooLong = 100000L;
            // L es usado para indicar que esta variable es de tipo long o ulong
            // un valor sin este sufijo es tratado como int o uint dependiendo del tamaño.

            // Ulong - Entero de 64 bits sin signo
            // (0 <= ulong <= 18,446,744,073,709,551,615)
            ulong fooUlong = 100000L;

            // Float - Precisión simple de 32 bits. IEEE 754 Coma flotante
            // Precisión: 7 dígitos
            float fooFloat = 234.5f;
            // f es usado para indicar que el valor de esta variable es de tipo float
            // de otra manera sería tratado como si fuera de tipo double.

            // Double - Doble precisión de 32 bits. IEEE 754 Coma flotante
            // Precisión: 15-16 dígitos
            double fooDouble = 123.4;

            // Bool - true & false (verdadero y falso)
            bool fooBoolean = true;
            bool barBoolean = false;

            // Char - Un solo caracter Unicode de 16 bits
            char fooChar = 'A';

            // Strings
            string fooString = "My string is here!";
            Console.WriteLine(fooString);

            // Formato de cadenas
            string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
            Console.WriteLine(fooFormattedString);

            // Formato de fechas
            DateTime fooDate = DateTime.Now;
            Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));

            // \n es un caracter de escape que comienza una nueva línea
            string barString = "Printing on a new line?\nNo Problem!";
            Console.WriteLine(barString);

            // Puede ser escrito mejor usando el símbolo @
            string bazString = @"Here's some stuff
    on a new line!";
            Console.WriteLine(bazString);

            // Las comillas deben ser escapadas
            // usa \" para escaparlas
            string quotedString = "some \"quoted\" stuff";
            Console.WriteLine(quotedString);

            // usa "" cuando las cadenas comiencen con @
            string quotedString2 = @"some MORE ""quoted"" stuff";
            Console.WriteLine(quotedString2);

            // Usa const o readonly para hacer las variables inmutables
            // los valores const son calculados en tiempo de compilación
            const int HOURS_I_WORK_PER_WEEK = 9001;

            // Tipos que aceptan valores NULL (Nullable)
            // cualquier tipo de dato puede ser un tipo nulo añadiendole el sufijo ?
            // <tipo>? <variable> = <valor>
            int? nullable = null;
            Console.WriteLine("Nullable variable: " + nullable);

            // Para usar valores nulos, tienes que usar la propiedad Value
            // o usar conversión explícita
            string? nullableString = "not null";
            Console.WriteLine("Nullable value is: " + nullableString.Value + " or: " + (string) nullableString );

            // ?? is una manera corta de especificar valores por defecto
            // en caso de que la variable sea null
            int notNullable = nullable ?? 0;
            Console.WriteLine("Not nullable variable: " + notNullable);

            // var - el compilador escogerá el tipo de dato más apropiado basado en el valor
            var fooImplicit = true;

            ///////////////////////////////////////////////////
            // Estructura de datos
            ///////////////////////////////////////////////////
            Console.WriteLine("\n->Data Structures");

            // Arreglos
            // El tamaño del arreglo debe decidirse al momento de la declaración
            // El formato para declarar un arreglo es el siguiente:
            // <tipo_de_dato>[] <nombre_variable> = new <tipo_de_dato>[<tamaño>];
            int[] intArray = new int[10];
            string[] stringArray = new string[1];
            bool[] boolArray = new bool[100];

            // Otra forma de declarar e inicializar un arreglo
            int[] y = { 9000, 1000, 1337 };

            // Indexar arreglos - Acceder a un elemento
            Console.WriteLine("intArray @ 0: " + intArray[0]);

            // Los arreglos son de índice cero y son mutables.
            intArray[1] = 1;
            Console.WriteLine("intArray @ 1: " + intArray[1]); // => 1

            // Listas
            // Las listas son usadas más frecuentemente que los arreglos ya que son más flexibles
            // El formato para declarar una lista es el siguiente:
            // List<tipo_de_dato> <nombre_variable> = new List<tipo_de_dato>();
            List<int> intList = new List<int>();
            List<string> stringList = new List<string>();

            // Otra forma de declarar e inicializar una lista
            List<int> z = new List<int> { 9000, 1000, 1337 };

            // Indexar una lista - Acceder a un elemento
            // Las listas son de índice cero y son mutables.
            Console.WriteLine("z @ 0: " + z[2]);

            // Las listas no tienen valores por defecto;
            // Un valor debe ser añadido antes de acceder al índice
            intList.Add(1);
            Console.WriteLine("intList @ 0: " + intList[0]);


            // Otras estructuras de datos a chequear:
            //
            // Pilas/Colas
            // Diccionarios
            // Colecciones de sólo lectura
            // Tuplas (.Net 4+)


            ///////////////////////////////////////
            // Operadores
            ///////////////////////////////////////
            Console.WriteLine("\n->Operators");

            int i1 = 1, i2 = 2; // Modo corto para múltiples declaraciones

            // La aritmética es sencilla
            Console.WriteLine("1+2 = " + (i1 + i2)); // => 3
            Console.WriteLine("2-1 = " + (i2 - i1)); // => 1
            Console.WriteLine("2*1 = " + (i2 * i1)); // => 2
            Console.WriteLine("1/2 = " + (i1 / i2)); // => 0 (0.5 truncated down)

            // Módulo
            Console.WriteLine("11%3 = " + (11 % 3)); // => 2

            // Operadores de comparación
            Console.WriteLine("3 == 2? " + (3 == 2)); // => false
            Console.WriteLine("3 != 2? " + (3 != 2)); // => true
            Console.WriteLine("3 > 2? " + (3 > 2)); // => true
            Console.WriteLine("3 < 2? " + (3 < 2)); // => false
            Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
            Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true

            // Operadores a nivel de bits
            /*
            ~       Complemento a nivel de bits
            <<      Desplazamiento a la izquierda con signo
            >>      Desplazamiento a la derecha con signo
            >>>     Desplazamiento a la derecha sin signo
            &       AND a nivel de bits
            ^       XOR a nivel de bits
            |       OR a nivel de bits
            */

            // Incremento
            int i = 0;
            Console.WriteLine("\n->Inc/Dec-remento");
            Console.WriteLine(i++); //i = 1. Posincrementación
            Console.WriteLine(++i); //i = 2. Preincremento
            Console.WriteLine(i--); //i = 1. Posdecremento
            Console.WriteLine(--i); //i = 0. Predecremento


            ///////////////////////////////////////
            // Estructuras de control
            ///////////////////////////////////////
            Console.WriteLine("\n->Control Structures");

            // Las condiciones if son como en lenguaje c
            int j = 10;
            if (j == 10)
            {
                Console.WriteLine("I get printed");
            }
            else if (j > 10)
            {
                Console.WriteLine("I don't");
            }
            else
            {
                Console.WriteLine("I also don't");
            }

            // Operador ternario
            // Un simple if/else puede ser escrito de la siguiente manera;
            // <condición> ? <true> : <false>
            string isTrue = (true) ? "True" : "False";
            Console.WriteLine("Ternary demo: " + isTrue);


            // Bucle while
            int fooWhile = 0;
            while (fooWhile < 100)
            {
                //Console.WriteLine(fooWhile);
                //Incrementar el contador
                //Iterar 99 veces, fooWhile 0->99
                fooWhile++;
            }
            Console.WriteLine("fooWhile Value: " + fooWhile);

            // Bucle Do While
            int fooDoWhile = 0;
            do
            {
                //Console.WriteLine(fooDoWhile);
                //Incrementar el contador
                //Iterar 99 veces, fooDoWhile 0->99
                fooDoWhile++;
            } while (fooDoWhile < 100);
            Console.WriteLine("fooDoWhile Value: " + fooDoWhile);

            // Bucle For
            int fooFor;
            //Estructura del bucle for => for(<declaración_inicial>; <condición>; <incremento>)
            for (fooFor = 0; fooFor < 10; fooFor++)
            {
                //Console.WriteLine(fooFor);
                //Iterated 10 times, fooFor 0->9
            }
            Console.WriteLine("fooFor Value: " + fooFor);

            // Switch Case
            // El switch funciona con los tipos de datos byte, short, char e int
            // También funciona con las enumeraciones (discutidos en in Tipos Enum),
            // la clase string y algunas clases especiales que encapsulan
            // tipos primitivos: Character, Byte, Short, Integer.
            int month = 3;
            string monthString;
            switch (month)
            {
                case 1:
                    monthString = "January";
                    break;
                case 2:
                    monthString = "February";
                    break;
                case 3:
                    monthString = "March";
                    break;
                default:
                    monthString = "Some other month";
                    break;
            }
            Console.WriteLine("Switch Case Result: " + monthString);


            ////////////////////////////////
            // Conversión de tipos de datos
            ////////////////////////////////

            // Convertir datos

            // Convertir String a Integer
            // esto generará una excepción al fallar la conversión
            int.Parse("123");//retorna una versión entera de "123"

            // TryParse establece la variable a un tipo por defecto
            // en este caso: 0
            int tryInt;
            int.TryParse("123", out tryInt);

            // Convertir Integer a String
            // La clase Convert tiene algunos métodos para facilitar las conversiones
            Convert.ToString(123);

            ///////////////////////////////////////
            // Clases y Funciones
            ///////////////////////////////////////

            Console.WriteLine("\n->Classes & Functions");

            // (Definición de la clase Bicycle (Bicicleta))

            // Usar new para instanciar una clase
            Bicycle trek = new Bicycle();

            // Llamar a los métodos del objeto
            trek.speedUp(3); // Siempre deberías usar métodos setter y métodos getter
            trek.setCadence(100);

            // ToString es una convención para mostrar el valor del objeto.
            Console.WriteLine("trek info: " + trek.ToString());

            // Instanciar otra nueva bicicleta
            Bicycle octo = new Bicycle(5, 10);
            Console.WriteLine("octo info: " + octo.ToString());

            // Instanciar un Penny Farthing (Biciclo)
            PennyFarthing funbike = new PennyFarthing(1, 10);
            Console.WriteLine("funbike info: " + funbike.ToString());

            Console.Read();
        } // Fin del método main


    } // Fin de la clase LearnCSharp

    // Puedes incluir otras clases en un archivo .cs


    // Sintaxis para la declaración de clases:
    // <public/private/protected> class <nombre_de_clase>{
    //    //campos, constructores, funciones todo adentro de la clase.
    //    //las funciones son llamadas métodos como en java.
    // }

    public class Bicycle
    {
        // Campos/Variables de la clase Bicycle
        public int cadence; // Public: Accesible desde cualquier lado
        private int _speed;  // Private: Sólo es accesible desde dentro de la clase
        protected int gear; // Protected: Accesible desde clases y subclases
        internal int wheels; // Internal: Accesible en el ensamblado
        string name; // Todo es privado por defecto: Sólo es accesible desde dentro de esta clase

        // Enum es un tipo valor que consiste un una serie de constantes con nombres
        public enum Brand
        {
            AIST,
            BMC,
            Electra,
            Gitane
        }
        // Definimos este tipo dentro de la clase Bicycle, por lo tanto es un tipo anidado
        // El código afuera de esta clase debería referenciar este tipo como Bicycle.Brand

        public Brand brand; // Declaramos un tipo enum, podemos declarar un campo de este tipo

        // Los miembros estáticos pertenecen al tipo mismo, no a un objeto en específico.
        static public int bicyclesCreated = 0;
        // Puedes acceder a ellos sin referenciar ningún objeto:
        // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);

        // Los valores readonly (Sólo lectura) son establecidos en tiempo de ejecución
        // sólo pueden ser asignados al momento de la declaración o dentro de un constructor
        readonly bool hasCardsInSpokes = false; // privado de sólo lectura

        // Los constructores son una forma de crear clases
        // Este es un constructor por defecto
        private Bicycle()
        {
            gear = 1;
            cadence = 50;
            _speed = 5;
            name = "Bontrager";
            brand = Brand.AIST;
            bicyclesCreated++;
        }

        // Este es un constructor específico (contiene argumentos)
        public Bicycle(int startCadence, int startSpeed, int startGear,
                       string name, bool hasCardsInSpokes, Brand brand)
        {
            this.gear = startGear; // La palabra reservada "this" señala el objeto actual
            this.cadence = startCadence;
            this._speed = startSpeed;
            this.name = name; // Puede ser útil cuando hay un conflicto de nombres
            this.hasCardsInSpokes = hasCardsInSpokes;
            this.brand = brand;
        }

        // Los constructores pueden ser encadenados
        public Bicycle(int startCadence, int startSpeed, Brand brand) :
            this(startCadence, startSpeed, 0, "big wheels", true)
        {
        }

        // Sintaxis para Funciones:
        // <public/private/protected> <tipo_retorno> <nombre_funcion>(<args>)

        // Las clases pueden implementar getters y setters para sus campos
        // o pueden implementar propiedades

        // Sintaxis para la declaración de métodos:
        // <ámbito> <tipo_retorno> <nombre_método>(<argumentos>)
        public int GetCadence()
        {
            return cadence;
        }

        // Los métodos void no requieren usar return
        public void SetCadence(int newValue)
        {
            cadence = newValue;
        }

        // La palabra reservada virtual indica que este método puede ser sobrescrito
        public virtual void SetGear(int newValue)
        {
            gear = newValue;
        }

        // Los parámetros de un método pueden tener valores por defecto.
        // En este caso, los métodos pueden ser llamados omitiendo esos parámetros
        public void SpeedUp(int increment = 1)
        {
            _speed += increment;
        }

        public void SlowDown(int decrement = 1)
        {
            _speed -= decrement;
        }

        // Propiedades y valores get/set
        // Cuando los datos sólo necesitan ser accedidos, considera usar propiedades.
        // Las propiedades pueden tener get, set o ambos
        private bool _hasTassles; // variable privada
        public bool HasTassles // acceso público
        {
            get { return _hasTassles; }
            set { _hasTassles = value; }
        }

        // Las propiedades pueden ser auto implementadas
        public int FrameSize
        {
            get;
            // Puedes especificar modificadores de acceso tanto para get como para set
            // esto significa que sólo dentro de la clase Bicycle se puede modificar Framesize
            private set;
        }

        //Método para mostrar los valores de atributos de este objeto.
        public override string ToString()
        {
            return "gear: " + gear +
                    " cadence: " + cadence +
                    " speed: " + _speed +
                    " name: " + name +
                    " cards in spokes: " + (hasCardsInSpokes ? "yes" : "no") +
                    "\n------------------------------\n"
                    ;
        }

        // Los métodos también pueden ser estáticos. Puede ser útil para métodos de ayuda
        public static bool DidWeCreateEnoughBycles()
        {
            // Dentro de un método esático,
            // Sólo podemos hacer referencia a miembros estáticos de clases
            return bicyclesCreated > 9000;
        }   // Si tu clase sólo necesita miembros estáticos,
            // considera establecer la clase como static.

    } // fin de la clase Bicycle

    // PennyFarthing es una subclase de Bicycle
    class PennyFarthing : Bicycle
    {
        // (Penny Farthings son las bicicletas con una rueda delantera enorme.
        // No tienen engranajes.)

        // llamar al constructor de la clase padre
        public PennyFarthing(int startCadence, int startSpeed) :
            base(startCadence, startSpeed, 0, "PennyFarthing", true)
        {
        }

        public override void SetGear(int gear)
        {
            gear = 0;
        }

        public override string ToString()
        {
            string result = "PennyFarthing bicycle ";
            result += base.ToString(); // Llamar a la versión base del método
            return reuslt;
        }
    }

    // Las interfaces sólo contienen las declaraciones
    // de los miembros, sin la implementación.
    interface IJumpable
    {
        void Jump(int meters); // todos los miembros de interfaces son implícitamente públicos
    }

    interface IBreakable
    {
        // Las interfaces pueden contener tanto propiedades como métodos, campos y eventos
        bool Broken { get; }
    }

    // Las clases sólo heredan de alguna otra clase, pero pueden implementar
    // cualquier cantidad de interfaces
    class MountainBike : Bicycle, IJumpable, IBreakable
    {
        int damage = 0;

        public void Jump(int meters)
        {
            damage += meters;
        }

        public void Broken
        {
            get
            {
                return damage > 100;
            }
        }
    }
} // Fin del espacio de nombres

Temas no cubiertos

Lecturas recomendadas

Convenciones de código de C#


¿Tienes una sugerencia o rectificación? Abre un issue en el repositorio de GitHub, o haz un pull request tu mismo

Originalmente contribuido por Irfan Charania, y actualizado por 5 colaborador(es).