{"id":22331144,"url":"https://github.com/sammmte/programacion-csharp","last_synced_at":"2026-02-02T17:09:14.450Z","repository":{"id":143998228,"uuid":"260049199","full_name":"Sammmte/Programacion-CSharp","owner":"Sammmte","description":"Documento con información sobre como programar en C#","archived":false,"fork":false,"pushed_at":"2020-07-18T01:20:44.000Z","size":31,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-13T08:48:35.515Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sammmte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-29T21:24:19.000Z","updated_at":"2020-07-18T01:20:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"4ef6d527-3aa4-47a4-894d-772317e03eed","html_url":"https://github.com/Sammmte/Programacion-CSharp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Sammmte/Programacion-CSharp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sammmte%2FProgramacion-CSharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sammmte%2FProgramacion-CSharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sammmte%2FProgramacion-CSharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sammmte%2FProgramacion-CSharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sammmte","download_url":"https://codeload.github.com/Sammmte/Programacion-CSharp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sammmte%2FProgramacion-CSharp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29015813,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-02T16:17:30.374Z","status":"ssl_error","status_checked_at":"2026-02-02T15:58:50.469Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-04T04:09:53.662Z","updated_at":"2026-02-02T17:09:14.435Z","avatar_url":"https://github.com/Sammmte.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Programación en C#\r\n\r\n## Variables:\r\n\r\nLas variables son espacios en memoria que guardan un valor un tipo determinado. A continuación un ejemplo de como declarar una variable:\r\n\r\n```csharp\r\nint miVariable = 3;\r\n//[Tipo][Nombre] = [Valor]\r\n```\r\n\r\nLa asignación de un valor es opcional en la creación de una variable. El siguiente ejemplo muestra como crear una variable a la que no se le asigna ningun valor:\r\n\r\n```csharp\r\nint miVariable;\r\n```\r\n\r\nLas variables dependen de la existencia de tipos de dato. En C#, así como en la mayoría de lenguajes de programación, nosotros podemos crear nuestros propios tipos de dato. Esto se explicará en profundidad mucho más adelante.\r\n\r\nPor otro lado existen los llamados tipos \"primitivos\". Estos son tipos de datos que vienen con el lenguaje. A continuación se muestran todos los tipos de datos primitivos que existen en C#:\r\n\r\n```csharp\r\nint -\u003e Número entero de 32 bits. Todo número que no tenga coma. Permite negativos.\r\nMínimo: -2.147.483.648         Máximo: +2.147.483.647         Peso: 4 bytes\r\n\r\nfloat -\u003e Número con decimales. Permite negativos.\r\n        Mínimo: -3.4 × 10^38                 Máximo: +3.4 × 10^38                Peso: 4 bytes\r\n\r\nchar -\u003e Guarda caracteres como letras, números o signos. Se asigna usando comillas simples (ej: char a = ‘$’).\r\n        Peso: 2 bytes\r\n\r\n\r\nbool -\u003e Almacena verdadero o falso, true o false.\r\n        Peso: 1 byte\r\n\r\n\r\nstring -\u003e Cadena de caracteres. Se asigna usando comillas dobles (ej: string a = \"hola\").\r\n        Peso: Variado. Siendo simplistas podríamos pensar que son 2 bytes por letra (char)\r\n\r\n\r\ndouble -\u003e Número con decimales. Tiene el doble de la precisión en decimales que el float. Permite negativos.\r\n        Mínimo: -1.7976931348623157E+308        Máximo: 1.7976931348623157E+308 Peso: 8 bytes\r\n\r\n\r\nlong -\u003e Número entero de 64 bits. Permite negativos.\r\n        Mínimo: -9.223.372.036.854.775.808         Máximo: 9.223.372.036.854.775.807   Peso: 8 bytes\r\n\r\n\r\nshort -\u003e Número entero de 16 bits. Permite negativos.\r\n        Mínimo: -32.768                         Máximo: 32.767        Peso: 2 bytes\r\n\r\n\r\nbyte -\u003e Número entero de 8 bits. No permite negativos.\r\n        Mínimo: 0                                Máximo: 255                Peso: 1 byte\r\n\r\n\r\nsbyte -\u003e Igual que el byte, pero admite negativos. La ‘S’ es de Signed (con signo).\r\n        Mínimo: -128                                 Máximo: 127                 Peso: 1 byte\r\n\r\n\r\nuint -\u003e Igual que el int, pero no admite negativos. La ‘U’ es de Unsigned (sin signo).\r\n        Mínimo: 0                                Máximo: 4.394.967.395        Peso: 4 bytes\r\n\r\n\r\nushort -\u003e Igual que el short, pero no admite negativos.\r\n        Mínimo: 0                                 Máximo: 65535        Peso: 2 bytes\r\n\r\n\r\nulong -\u003e Igual que el long, pero no admite negativos.\r\n        Mínimo: 0                        Máximo: 18446744073709551615        Peso: 8 bytes\r\n```\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\tfloat b = 5.4f;\r\n\tchar c = ‘#’;\r\n\tbool d = true;\r\n\tstring e = \"Marcos\";\r\n}\r\n```\r\n\r\n## Constantes:\r\n\r\nTambién existen las constantes. Se declaran con la palabra reservada **const** y se asignan en la misma línea en la que se declaran. Su valor no puede cambiar.\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tconst float gravedad = 9.81f;\r\n\r\n\tgravedad = 3.2f //Esto dará un error. Las constantes no pueden cambiar su valor.\r\n}\r\n```\r\n\r\n## Operadores\r\n\r\nLos operadores son símbolos que nos permiten realizar una operación particular entre datos constantes o variables. A continuación algunos de los operadores básicos de C#.\r\n\r\n### Operadores Matemáticos:\r\n\r\nLos operadores matemáticos nos permiten realizar operaciones matemáticas entre 2 valores numéricos. Las reglas del algebra lineal se aplican a la hora de crear cálculos combinados.\r\n\r\n```csharp\r\nint a = 3;\r\nint b = 4;\r\nint c = 5;\r\n\r\nint resultado = a + b * c;\r\n//Como en un calculo combinado comun se aplica la regla de separación de términos. La multiplicacion se realizará primero y luego la suma entre el resultado de la multiplicación y el valor restante. El resultado de esta operación es: 23\r\n```\r\n\r\nA continuación los posibles operadores:\r\n\r\n- Suma ---\u003e +\r\n- Resta ---\u003e -\r\n- Multiplicación ---\u003e *\r\n- División ---\u003e /\r\n- Resto ---\u003e %\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 7; //Defino 2 variables. \"a\" y \"b\"\r\n\tint b = 4;\r\n\tint suma = a + b; //suma 2 valores\r\n\tint resta = a -b; //resta 2 valores\r\n\tint multiplicacion = a * b; //multiplica 2 valores\r\n\tint division = a / b; //divide 2 valores. Da como resultado el cociente.\r\n\tint modulo = a % b; //divide 2 valores. Da como resultado el resto.\r\n}\r\n```\r\n\r\nTambién es posible encontrar operadores matemáticos en otros contextos y con usos que no estén relacionados a la matemática. Por ejemplo, el operador suma (+) puede usarse con variables de tipo **string**. En este caso el operador de suma significa **concatenar**\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tstring nombre = \"Santiago\";\r\n\tstring apellido = \"Perez\";\r\n\r\n\tstring nombreYApellido = nombre + apellido; //concatenar\r\n\t//nombreYApellido tendrá dentro el valor: \"Santiago Perez\". Todo junto.\r\n}\r\n```\r\n\r\n## Operadores de Asignación:\r\n\r\nEstos operadores sirven para asignar un valor a una variable. Siempre la variable va del lado izquierdo y el valor del derecho.\r\n\r\n- Asignación Simple ---\u003e =\r\n- Suma y asignación ---\u003e +=\r\n- Resta y asignación ---\u003e -=\r\n- Multiplicación y asignación ---\u003e *=\r\n- División y asignación ---\u003e /=\r\n- Resto y asignación ---\u003e %=\r\n- Incremento en 1 ---\u003e ++\r\n- Decremento en 1 ---\u003e --\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15; //Asignación simple. a tendrá el valor asignado, en este caso 15.\r\n\tint b = a = 10; //Se puede asignar un mismo valor a más una variable a la vez.\r\n\ta += 10; //Se suma 10 al valor que actualmente tiene a y se le asigna el resultado. Igual a poner a = a + 10;\r\n\ta -= 10; //Se resta 10 al valor que actualmente tiene a y se le asigna el resultado. Igual a poner a = a - 10;\r\n\ta *= 10; //Se multiplica por 10 el valor que actualmente tiene a y se le asigna el resultado. Igual a poner a = a * 10;\r\n\ta /= 10; //Se divide por 10 el valor que actualmente tiene a y se le asigna el resultado. Igual a poner a = a / 10;\r\n\ta %= 10; //Se divide por 10 el valor que actualmente tiene a y se le asigna el resto. Igual a poner a = a % 10;\r\n\ta++; //Esto es lo mismo que poner a += 1 ó a = a + 1;\r\n\ta--; //Esto es lo mismo que poner a -= 1 ó a = a - 1;\r\n}\r\n```\r\n\r\n## Operadores de Comparación:\r\n\r\nEstos operadores dan como resultado de su operación un bool (true o false). Se evalúa de izquierda a derecha.\r\n\r\n- Igual a ---\u003e ==\r\n- Desigual a ---\u003e !=\r\n- Menor que ---\u003e \u003c\r\n- Mayor que ---\u003e \u003e\r\n- Menor o igual que ---\u003e \u003c=\r\n- Mayor o igual que ---\u003e \u003e=\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 1\r\n\tint b = 10;\r\n\tbool respuesta;\r\n\trespuesta = (a == b); //Evalua si a es igual a b, si son iguales el resultado será true, sino false.\r\n\trespuesta = (a != b); //Evalua si a no es igual a b, si no son iguales el resultado será true, sino false.\r\n\trespuesta = (a \u003c b); //Evalua si a es menor a b, si es menor el resultado será true, sino false.\r\n\trespuesta = (a \u003e b); //Evalua si a es mayor a b, si es mayor el resultado será true, sino false.\r\n\trespuesta = (a \u003c= b); //Evalua si a es menor o igual a b, si es menor o igual el resultado será true, sino false.\r\n\trespuesta = (a \u003e= b); //Evalua si a es mayor o igual a b, si es mayor o igual el resultado será true, sino false.\r\n}\r\n```\r\n\r\n## Operadores Lógicos:\r\n\r\nSon también operadores de comparación que sólo funcionan con bools. También retornan un bool como resultado.\r\n\r\n- Operador AND (‘y’ en inglés) ---\u003e \u0026\u0026\r\n- Operador OR (‘o’ en inglés) ---\u003e ||\r\n- Operador NOT (‘no’ en inglés) ---\u003e !\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\tint b = 10;\r\n\tbool respuesta;\r\n\trespuesta = (a \u003c b) \u0026\u0026 (a == 9); //AND //Se deben cumplir TODAS las condiciones a la vez. a debe ser menor que b Y también igual a 9. Si TODAS se cumplen, retorna true, sino false. Si una sola condición NO se cumple, las siguientes no se evaluarán.\r\n\tSi una condición no se cumple, las condiciones que le siguen no se evaluarán.\r\n\trespuesta = (a \u003c b) || (a == 9); //OR //Se debe cumplir AL MENOS UNA de las condiciones. Si CUALQUIERA de las condiciones se cumple retorna true, si NINGUNA se cumple retorna false. Si una condición se cumple, las condiciones que le siguen no se evaluarán.\r\n\trespuesta = !(a \u003c b); //El operador NOT (! signo de exclamación) retornará al revés del resultado de la condición dada. Es decir, al agregarle el signo de exclamación antes de la condición hará que convierta el resultado en lo contrario. Si (a \u003c b) es igual a true, !(a \u003c b) sera igual a false y viceversa.\r\n}\r\n```\r\n\r\n## Tabla de la verdad:\r\n\r\nLa siguiente tabla ilustra muestra, según la operación aplicada, que resultado se arroja en función de 2 valores dados.\r\n\r\n### OPERADOR AND (\u0026\u0026):\r\n\r\n![](https://github.com/Sammmte/Programacion-CSharp/blob/master/readme-resources/and-true-table.PNG)\r\n\r\n### OPERADOR OR (||):\r\n\r\n![](https://github.com/Sammmte/Programacion-CSharp/blob/master/readme-resources/or-true-table.PNG)\r\n\r\n## Condicionales\r\n\r\n### Bloque IF:\r\n\r\nEl bloque **if** evalúa bools dentro de sus paréntesis. Si lo que tiene dentro es igual a true, entra al bloque, sino no entra.\r\nUn if puede ser seguido por un bloque **else if** o **else**.\r\nEl bloque **else if** se evalúa si el anterior bloque (que puede ser if u otro else if) obtuvó un false. Es necesario que la condición evaluada por este bloque sea igual a true para que entre al mismo, si es false no entrará.\r\nEl bloque else en cambio no evalúa nada, sino que entra sólo si el anterior bloque obtuvo como resultado false.\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\tint b = 10;\r\n\r\n\tif(a == b) //si a es igual a b, entrará aquí\r\n\t{\r\n\t    Console.WriteLine(\"somos iguales\");\r\n\t}\r\n\telse if(a \u003c b) //si el anterior bloque dio false, evaluará en este si, en cambio, a es menor a b.\r\n\t{\r\n\t    Console.WriteLine(\"soy menor\");\r\n\t}\r\n\telse //Si todas las anteriores dieron false, entrará aquí\r\n\t{\r\n\t    Console.WriteLine(\"soy mayor\");\r\n\t}\r\n\r\n\t//Este conjunto de bloques se puede leer coloquialmente de la siguiente manera:\r\n\t//Si a es igual a b, muestra \"somos iguales\" en pantalla\r\n\t//Si, en cambio, a es menor a b, muestra \"soy menor\" en pantalla\r\n\t//Si ninguna de las anteriores fue verdadera, muestra \"soy mayor\" en pantalla.\r\n\r\n\t//Porque en el bloque else muestro \"soy mayor\"? Porque si a no es igual a b y tampoco es menor, inequivocamente es mayor a b.\r\n}\r\n```\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\tint b = 10;\r\n\r\n\tif(a == b \u0026\u0026 a == 15) \r\n\t{\r\n\t    Console.WriteLine(\"a y b son iguales a 15\");\r\n\t}\r\n\telse if(a \u003c b || a == 15)\r\n\t{\r\n\t    Console.WriteLine(\"a es menor que b o es igual a 15\");\r\n\t}\r\n\telse if(!(a \u003c b))\r\n\t{\r\n\t    Console.WriteLine(\"a no es menor que b\");\r\n\t}\r\n}\r\n```\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\t//Esto es válido, porque es una expresión bool\r\n\t//Este if siempre entrará, porque siempre es true\r\n\t//Por supuesto, hacer esto en un proyecto real no tiene sentido\r\n\tif(true)\r\n\t{\r\n\t\tConsole.WriteLine(\"Que bueno que siempre vean esto\");\r\n\t}\r\n\r\n\t//Esto también es válido, este if jamás entrará\r\n\t//Nuevamente, en un proyecto real no tiene sentido\r\n\tif(false)\r\n\t{\r\n\t\tConsole.WriteLine(\"Que lastima que jamas vean esto\");\r\n\t}\r\n}\r\n```\r\n\r\n### Contextos y anidamiento\r\n\r\nLas variables \"viven\" en contextos definidos. Los contextos se definen mediante las llaves ({}).\r\nEl **if**, así como el **switch, while, do while, for** que veremos más adelante, crean contextos.\r\n\r\nLos contextos pueden anidarse dentro de otros contextos. \r\nEsto significa que puedo hacer un if dentro de otro, y luego otro dentro, y otro y otro.\r\nCuantos quiera, de hecho.\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tif(true)\r\n\t{\r\n\t\tConsole.WriteLine(\"Aca entro\");\r\n\t\t\r\n\t\tif(true)\r\n\t\t{\r\n\t\t\tConsole.WriteLine(\"Aca tambien\");\r\n\r\n\t\t\tif(true)\r\n\t\t\t{\r\n\t\t\t\tConsole.WriteLine(\"Y aca\");\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n```\r\n\r\n### Scope (o contexto de vida) de las variables\r\n\r\nCuando el contexto de una variable es destruido, la variable también se destruye.\r\nUna variable creada en un contexto puede ser accedida desde cualquier lugar del contexto o desde un subcontexto.\r\nVeamos un ejemplo. **Una función es un contexto**. Dentro de una función se puede crear un **if, que también es un contexto**.\r\nEn este caso el contexto del if es un subcontexto del de la función.\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint unaVariable = 3;\r\n\r\n\tif(true)\r\n\t{\r\n\t\t//Puedo usar \"unaVariable\" porque pertenece a un contexto \"padre\"\r\n\t\tunaVariable = 5;\r\n\t}\r\n}\r\n```\r\n\r\nComo dijimos, podemos usar variables en subcontextos del contexto en que fue creada, pero no podemos usarla en contextos superiores.\r\nSi las cosas fueran al revés en el ejemplo anterior y la variable fuera declarada dentro del if **no podríamos usarla fuera de su contexto.**\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tif(true)\r\n\t{\r\n\t\tint unaVariable = 5;\r\n\t}\r\n\r\n\t//Esto da error. Cuando se sale del if, es decir\r\n\t//el contexto del if es destruido, \"unaVariable\" también se destruye.\r\n\tunaVariable = 8;\r\n}\r\n```\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tif(true)\r\n\t{\r\n\t\tint unaVariable = 5;\r\n\r\n\t\tif(true)\r\n\t\t{\r\n\t\t\t//Esto si es válido, ya que este segundo if es\r\n\t\t\t//un subcontexto del primer if\r\n\t\t\t//que fue donde se declaró \"unaVariable\"\r\n\t\t\tunaVariable = 8;\r\n\t\t}\r\n\t}\r\n}\r\n```\r\n\r\n### Bloque SWITCH\r\n\r\nEl bloque **switch** evalúa si la expresión dada (la variable) es igual a alguno de los casos expuestos en el bloque. Los deben ser valores **constantes**. Para determinar un caso se utiliza la palabra reservada **case**. Si ninguno de los casos cumple se puede utilizar un caso por defecto, con la palabra reservada **default**. Al final de cada caso se debe cerrar con la palabra reservada **break**.\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\t\r\n\tswitch(a) //La expresión debe ser variable\r\n\t{\r\n\t    case 1: //Los casos deben ser constantes\r\n\t        Console.WriteLine(\"a es igual a 1\");\r\n\t        break;\r\n\t    case 2:\r\n\t        Console.WriteLine(\"a es igual a 2\");\r\n\t        break;\r\n\t    default: //Opcional. Puede no estar.\r\n\t        Console.WriteLine(\"a es igual a \" + a);\r\n\t        break;\r\n\t}\r\n}\r\n```\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\tint b = 10;\r\n\t\r\n\tswitch(a) //La expresión debe ser variable\r\n\t{\r\n\t    case b: //ESTO NO ESTA PERMITIDO. DARÁ ERROR.\r\n\t\t\tConsole.WriteLine(\"Algo\");\r\n\t\t\tbreak;\r\n\t}\r\n}\r\n```\r\n\r\n## Bucles:\r\n\r\n### Bloque WHILE:\r\n\r\nEl bloque while, al igual que el if, evalúa bools dentro de sus paréntesis. Si lo que tiene dentro es igual a true, entra al bloque, sino no entra. El bloque se ejecutará una y otra vez hasta que la condición dentro de sus paréntesis sean igual a false.\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\tint b = 10;\r\n\r\n\twhile(a \u003e b) //Mientras que a sea mayor que b, ejecutará el bloque\r\n\t{\r\n\t    a--; //Como vimos antes, esto resta 1 a lo que tiene a.\r\n\t\tConsole.WriteLine(a);\r\n\t}\r\n\t//Entrará y restará 1 a la variable a. En el momento en que (a \u003e b) sea igual a false el bloque dejará de ejecutarse. Exactamente en el momento en que a sea igual a b.\r\n}\r\n\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\tint b = 10;\r\n\r\n\twhile(a == 15)\r\n\t{\r\n\t    //Si yo no hago nada para cambiar el resultado de la condición, sigue siendo     \r\n\t\t//un bucle infinito, ya que siempre será true. Se ha de tener mucho cuidado con esto.\r\n\t}\r\n}\r\n\r\npublic static void Main()\r\n{\r\n\twhile(true) //esto es válido y es básicamente un bucle infinito.\r\n\t{\r\n\t    Console.WriteLine(\"SÁQUENME DE ACÁ\");\r\n\t}\r\n}\r\n```\r\n\r\n### Bloque Do-While:\r\n\r\nUna variante del bucle while. La diferencia principal radica en que el bloque while se ejecutará **si y sólo si la condición que evalúa es igual a true**. En cambio do-while ejecutará su bloque **por lo menos una vez**, luego de ejecutar la primera vez si la condición evaluada fuera igual a false no se volverá a ejecutar.\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint a = 15;\r\n\tint b = 10;\r\n\r\n\t//La condición es que a sea igual a b, en un while común no entraría\r\n\t//pero en un do-while entrará al menos una vez, independientemente de la\r\n\t//condición\r\n\tdo\r\n\t{\r\n\t\tConsole.WriteLine(\"ENTRO UNA VEZ\");\r\n\t}\r\n\twhile(a == b); //Al final del while debe ir un punto y coma.\r\n}\r\n```\r\n\r\n### Bloque For:\r\n\r\nEl bucle for está diseñado para trabajar con una cantidad de iteraciones definida. Este bucle funciona al igual que los demás: ejecuta un bloque de código mientras una condición se cumpla.\r\nEl for consta de 3 partes ideales:\r\n1. Asignación: Se asigna un valor a una variable. Usualmente a un int.\r\n2. Condición: La condición que, mientras sea igual a true, hará que ejecute el bloque.\r\n3. Incremento/Decremento: Se suma o resta al valor utilizado en la asignación. Esto suele ser la razón que hace que la condición en algún momento sea igual a false.\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\t//for(asignacion ; condición ; incremento / decremento)\r\n\r\n\tfor(int i = 1; i \u003c= 10; i++) //Como nombre de la variable se suele usar la letra i\r\n\t{\r\n\t    Console.WriteLine(\"Iteracion numero: \" + i); //Aprovecho el valor de i\r\n\t}\r\n}\r\n```\r\n\r\n## Funciones:\r\n\r\nLas funciones son bloques de código que **pueden o no devolver un resultado y pueden o no recibir parámetros**. Independientemente de si devuelven o no un resultado, siempre ejecutarán el código que tengan adjunto. Siempre debe existir una función llamada Main() que representa el comienzo del programa.\r\nLas funciones constan de ciertos modificadores (como puede ser public), de un tipo de dato (como puede ser int o void), de un nombre seguido de paréntesis, donde puede o no recibir parámetros.\r\nLos parámetros son datos con los que la función puede operar. Variables, básicamente.\r\n\r\nLas funciones que tienen como tipo de dato **void** (que significa vacío) no devuelven nada. Las funciones que tienen cualquier otro tipo de dato devuelven un valor y estan obligadas a usar la sentencia **return** para retornar el valor, resultado de un operación. **void** no puede usarse como tipo de dato de una variable, solamente como tipo de dato de retorno de una función.\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\n//Devuelve un dato y no recibe nada\r\npublic static int DevolverUnNumero()\r\n{\r\n\treturn 3; //la palabra reservada ‘return’ sirve para devolver un dato por función\r\n    \t\t//se profundizará más adelante\r\n}\r\n\r\n//No devuelve nada ni recibe datos\r\npublic static void Saludar()\r\n{\r\n\tConsole.WriteLine(\"HOLA MAMA\");\r\n}\r\n\r\n//No devuelve nada y recibe un dato\r\npublic static void SaludarPorNombre(string nombre)\r\n{\r\n\tConsole.Write(\"HOLA \");\r\n\tConsole.WriteLine(nombre);\r\n}\r\n\r\n//Devuelve un dato y recibe dos datos\r\npublic static int RestarNumeros(int primerNumero, int segundoNumero)\r\n{\r\n\treturn primerNumero * segundoNumero;\r\n}\r\n```\r\n\r\nVimos como crear nuestras propias funciones. Para llamar/invocar esa función se debe escribir su nombre y seguidamente abrir y cerrar paréntesis. Si la función recibe parametros, estos van dentro de los paréntesis, en el orden en el que la función los recibe. Cuando una función recibe más de un parámetro, estos se deben separar con una coma. A continuación se muestra como llamarlas:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint miNumero = DevolverUnNumero(); \r\n\t//El valor que devuelve una funcion puede asignarse a una variable\r\n\r\n\tSaludar(); \r\n\t//Esta funcion no recibe ni devuelve nada, asique se invoca como se explicó anteriormente sin más.\r\n\r\n\tSaludarPorNombre(\"Santiago\");\r\n\t//Esta funcion recibe una string, asique le pasamos un valor string entre los paréntesis. Si no lo hacemos, nos arrojará error.\r\n\r\n\tint miResta = RestarNumeros(5, 3);\r\n\t//Esta funcion recibe 2 parámetros. Estos parametros deben pasarse en orden de como la función los pide. Por ejemplo, esta función resta números, y como vemos arriba en su código, resta el segundo número al primero, haciendo 5 menos 3. Si pasaramos los valores al revés, restaría 3 menos 5. Cuidado con el orden!\r\n\r\n\t//Adicionalmente devuelve un resultado, producto de una operación. En este caso una resta.\r\n}\r\n```\r\n\r\nPor ahora no hablaremos sobre las palabras reservadas **public** y **static**. Por el momento pensemos que es magia.\r\n\r\n## Sentencias de salto:\r\n\r\nLas sentencias de salto son herramientas para redireccionar el flujo del programa.\r\nLas sentencias posibles son:\r\n\r\n### break\r\n\r\nEsta sentencia rompe un bucle o un case del switch.\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tfor(int i = 0; i \u003c 10; i++)\r\n\t{\r\n\t    if(i == 5)\r\n\t    {\r\n\t        Console.WriteLine(\"YA NO NECESITO NADA DE ESTE BUCLE\");\r\n\t        break;\r\n\t    }\r\n\t}\r\n}\r\n```\r\n\r\n### continue\r\n\r\nDentro de un bucle salta a la siguiente iteración del mismo.\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tfor(int i = 0; i \u003c 10; i++)\r\n\t{\r\n\t    if(i == 5)\r\n\t    {\r\n\t        continue; //Si a mi me parece que el 5 no es un número groso\r\n\t                    //paso al siguiente. Lo que está después no se ejecuta.\r\n\t    }\r\n\r\n\t    Console.WriteLine(\"ESTE NUMERO ES GROSO: \" + i);\r\n\t}\r\n}\r\n```\r\n\r\n### return\r\n\r\nSe utiliza en funciones o propiedades para retornar un valor. Si la función devuelve void entonces solo termina con la función sin devolver nada. En este último caso la palabra **return** no es obligatoria.\r\n\r\n```csharp\r\npublic static int DevolverUnNumero()\r\n{\r\n\treturn 3;\r\n}\r\n\r\npublic static void NoHacerNada()\r\n{\r\n\treturn; //Esta función no hace absolutamente nada.\r\n}\r\n```\r\n\r\n### goto\r\n\r\nEsta sentencia se suele considerar prohibida por muchas razones. La principal de ellas es que hace que el flujo del programa sea un caos. Sin embargo en algunos pocos casos es aceptable usarla. Básicamente salta hacia una sentencia **label** creada en el programa. Los case del switch son sentencias label.\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tstring nombre;\r\n\r\n\tswitch(nombre)\r\n\t{\r\n\t        case \"Mariana\": \r\n\t                Console.WriteLine(\"Es buena chica, pero\");\r\n\t                goto case \"Roberta\"; //Si el nombre es Mariana, entra a este caso\r\n\t          \t\t//y luego salta al de Roberta también.\r\n\t        case \"Roberta\":\r\n\t                Console.WriteLine(\"es una estupida\");\r\n\t                break;\r\n\t        default:\r\n\t                Console.WriteLine(\"su nombre es \" + nombre);\r\n\t                break;\r\n\t}\r\n\r\n\t//Si el nombre es roberta va a mostrar:\r\n\r\n\t//es una estupida\r\n\r\n\t//Si el nombre es mariana va a mostrar:\r\n\r\n\t//Es buena chica, pero\r\n\t//es un estupida\r\n}\r\n```\r\n\r\n### throw\r\n \r\nPermite arrojar excepciones que cortan el flujo de ejecución hasta que alguien \"maneje\" la excepción. Se profundizará sobre su uso más adelante.\r\n\r\n## Arrays:\r\n\r\nLos arrays son variables que guardan una cantidad finita de datos de un mismo tipo. Por ejemplo, se puede crear un array de int, char, bool, string o incluso de arrays. \r\nLas variables que tienen dentro no poseen nombres identificadores, sino que son accedidos mediante su número de índice. El índice **siempre comienza con el número 0** y los arrays tienen una propiedad llamada **Length** que representa su cantidad de índices. El último índice **siempre es igual a su Length menos 1**. **ES MUY IMPORTANTE NO CONFUNDIR EL INDICE UN ARRAY CON EL VALOR QUE GUARDA DENTRO DE ÉL.**\r\n\r\n### Ejemplos:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n\tint[] array = new int[4]; //Se inicializa utilizando la palabra reservada new\r\n\t//entre corchetes se le pasa la cantidad de espacios que se quiere que tenga\r\n\r\n\t//Asigno valor a los espacios del array\r\n\tarray[0] = 3;\r\n\tarray[1] = 5;\r\n\tarray[2] = 10;\r\n\tarray[3] = 12; //Absolutamente siempre el último índice es igual al Length - 1\r\n\t\r\n\tint ultimoIndice = array.Length - 1;\r\n\r\n\tint primerValor = array[0];\r\n\tint ultimoValor = array[ultimoIndice]; \r\n\t//se puede usar una variable para referirse a un índice dinámicamente.\r\n}\r\n\r\npublic static void Main()\r\n{\r\n\tint[] array = new int[10]; \r\n\r\n\t//Los bloques for son especialmente útiles con los arrays\r\n\t//Se accede al Length de un array mediante el punto\r\n\tfor(int indice = 0; indice \u003c array.Length; indice++) \r\n\t{                                                        \r\n\t    array[indice] = indice; //Lleno el array con valores\r\n\t\t//En este caso el indice resulta ser igual al valor de su espacio. RECUERDA NO CONFUNDIR AMBAS COSAS\r\n\t    Console.WriteLine(\"El indice \" + indice + \" contiene el valor: \" + array[indice]);\r\n\t    //Muestro los valores del array por indice\r\n\t}\r\n}\r\n```\r\n\r\n## Jagged Array\r\n\r\nUn array de arrays se le conoce como Jagged Array.\r\n\r\n### Ejemplo:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n    int[][] jaggedArray = new int[3][4];\r\n\t//Esto es un array que contiene 3 arrays de enteros\r\n\t//A su vez, cada array de enteros tiene 4 enteros cada uno\r\n\t//Eso nos da un total de 12 enteros (3 x 4)\r\n}\r\n\r\npublic static void Main()\r\n{\r\n\tint[][] jaggedArray = new int[3][4];\r\n\r\n\t//Para obtener el Length de cada uno\r\n\tint lengthDelPrimerArray = jaggedArray[0].Length;\r\n\tint lengthDelSegundoArray = jaggedArray[1].Length;\r\n\tint lengthDelTercerArray = jaggedArray[2].Length;\r\n}\r\n```\r\n\r\n## Matrices\r\n\r\nUna matriz es como un array de arrays. Tiene ciertas diferencias en la utilizacion y la performance. Para obtener el Length de una dimensión de la matriz se usa la función GetLength, que recibe el numero de la dimensión de la que se quiere consultar, empezando por 0.\r\n\r\n### Ejemplo:\r\n\r\n```csharp\r\npublic static void Main()\r\n{\r\n    int[,] miMatriz = new int[2, 3];\r\n\t//Una matriz de 2 dimensiones, de 2x3. La cantidad de ints que puede albergar es igual a 2x3 = 6.\r\n}\r\n\r\npublic static void Main()\r\n{\r\n    int[,] miMatriz = new int[2, 3, 6];\r\n\t//Una matriz de 3 dimensiones, de 2x3x6. La cantidad de ints que puede albergar es igual a 2x3x6 = 36.\r\n}\r\n\r\npublic static void Main()\r\n{\r\n\tint[,] miMatriz = new int[3, 4, 5];\r\n\r\n\t//Para obtener el Length de una dimensión\r\n\tint lengthDeLaPrimeraDimension = miMatriz.GetLength(0);\r\n\tint lengthDeLaSegundaDimension = miMatriz.GetLength(1);\r\n\tint lengthDeLaTerceraDimension = miMatriz.GetLength(2);\r\n}\r\n```\r\n\r\n## Clases y Structs\r\n\r\nLas clases y structs son definiciones de un objeto. Básicamente nosotros podemos crear nuestros propios tipos de dato y luego utilizarlos para nuestros fines.\r\n\r\n```csharp\r\n//Asi declaramos una clase Perro. \r\n//Es decir, estamos creando una definición de lo que es un perro en nuestro programa\r\npublic class Perro\r\n{\r\n\t//Las clases pueden tener variables\r\n\tpublic string nombre;\r\n\t//O constantes, tambien\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\t//Esto es un constructor. Mas adelante hablaremos de ellos\r\n\tpublic Perro(string _nombre)\r\n\t{\r\n\t\tnombre = _nombre;\r\n\t}\r\n\r\n\t//Tambien muy seguramente tenga funciones o metodos. \r\n\t//Comunmente en el contexto de una clase a una funcion se le llama metodo\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n\r\n//De la misma podemos crear un struct Posicion2D\r\npublic struct Posicion2D\r\n{\r\n\tpublic int x;\r\n\tpublic int y;\r\n\r\n\t//Los structs también pueden tener constructores\r\n\tpublic Position2D(int _x, int _y)\r\n\t{\r\n\t\tx = _x;\r\n\t\ty = _y;\r\n\t}\r\n\t\r\n\t//Y por supuesto también métodos. Este es un ejemplo\r\n\tpublic Position2D SumarPosicion(Position2D otraPosicion)\r\n\t{\r\n\t\treturn new Position2D(otraPosicion.x + x, otraPosicion.y + y);\r\n\t}\r\n}\r\n```\r\n\r\nLas clases y los structs representan el molde de un objeto. Perse, no hacen nada, es necesario instanciarlos. Para ello utilizamos la palabra reservada **new** seguida del **constructor** de la clase o el struct, que lo que hará es crear un objeto a partir de su propia definición.\r\n\r\n```csharp\r\npublic class Program\r\n{\r\n\tpublic static void Main(string[] args)\r\n\t{\r\n\t\t//Creo mi objeto perro en funcion de su clase\r\n\t\tPerro miPerro = new Perro(); //Mas adelante hablaremos de constructores\r\n\r\n\t\tmiPerro.Ladrar(); //ahora que tengo un objeto puedo llamar a su funcion Ladrar. Yupi!\r\n\t}\r\n}\r\n\r\npublic class Perro\r\n{\r\n\tpublic string nombre;\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n```\r\n\r\n### Objetos\r\n\r\nLos objetos son instancias de una clase o un struct. \r\nEsto quiere decir que son un elemento útil creado en función de una definición (la clase o el struct). \r\nPara que nosotros podamos ejecutar comportamiento definido en una clase o struct, guardar información o leerla, debemos crear un objeto.\r\n Este puede tener valores diferentes a otros objetos de la misma clase o struct, pero nunca una estructura diferente. \r\nPor ejemplo, nuestra clase \"Perro\" tiene un nombre, osea que todos los perros de nuestro programa tendrán un nombre. \r\nCuando creamos un objeto nosotros podemos ponerle el nombre que queramos. \r\nHay que pensarlo como si estuvieramos hablando de objetos en la vida real, si creamos 2 objetos de la clase \"Perro\" **¡Estamos creando 2 perros!**. \r\nY si bien nosotros definimos que todos los perros tienen nombre, **esto no significa que los perros que creemos deban llamarse igual.\r\nPara acceder a las variables y métodos de un objeto se utiliza el operador \".\" (dot)**\r\n\r\n```csharp\r\npublic class Program\r\n{\r\n\tpublic static void Main(string[] args)\r\n\t{\r\n\t\t//Creo 2 objetos. Estos comparten clase y por lo tanto tendran las mismas caracteristicas, pero no necesariamente los mismos valores.\r\n\t\tPerro miPrimerPerro = new Perro();\r\n\t\tPerro miSegundoPerro = new Perro();\r\n\r\n\t\tmiPrimerPerro.nombre = \"Fido\"; //Mi primer perro se llama Fido\r\n\t\tmiSegundoPerro.nombre = \"Firulais\"; //Pero mi segundo perro se llama Firulais\r\n\r\n\t\tConsole.WriteLine(miPrimerPerro.nombre);\r\n\t\tConsole.WriteLine(miSegundoPerro.nombre);\r\n\t}\r\n}\r\n\r\npublic class Perro\r\n{\r\n\tpublic string nombre;\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n```\r\n\r\nEn nuestro ejemplo anterior, todos los perros que creemos tendrán nombre, pero este puede ser diferente entre ellos. Por otro lado esta la constante **cantidadDePatas** que es igual a 4. Al ser constante no puede cambiarse, por lo que los perros que creemos indefectiblemente tendrán 4 patas. Esta decisión en nuestro diseño no nos deja, por ejemplo, crear perros cojos. ¿Es esto malo? Depende de vos. Vos sos quien define como se compone un perro en tu programa ¡Podés hacer lo que quieras!\r\n\r\nEn lo que respecta a métodos, los perros anteriormente creados comparten por definición el método **\"Ladrar\"**. Los métodos representan acciones que un objeto puede ejecutar. Esto significa que todos nuestros perros por definición pueden ladrar.\r\n\r\n```csharp\r\npublic class Program\r\n{\r\n\tpublic static void Main(string[] args)\r\n\t{\r\n\t\tPerro miPrimerPerro = new Perro();\r\n\t\tPerro miSegundoPerro = new Perro();\r\n\r\n\t\tmiPrimerPerro.nombre = \"Fido\";\r\n\t\tmiSegundoPerro.nombre = \"Firulais\";\r\n\r\n\t\tmiPrimerPerro.Ladrar(); //La consola mostrara \"Guau!\" en ambos casos\r\n\t\tmiSegundoPerro.Ladrar();\r\n\t}\r\n}\r\n\r\npublic class Perro\r\n{\r\n\tpublic string nombre;\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n```\r\n\r\n### Constructores\r\n\r\nLos constructores son métodos especiales que poseen todas las clases y structs, implícita o explícitamente. \r\n**Esto significa que no es necesario definir a mano un constructor, ya que si no se hace siempre habrá uno por defecto.** \r\nA diferencia de los métodos comunes que vimos hasta ahora, los constructores se definen colocándole un modificador de acceso **(ej. public, private)** y el nombre de la clase, luego los paréntesis con parámetros si necesitara. \r\nLos constructores sirven para comunicar los datos necesarios para construir un objeto determinado. \r\nPor ejemplo, podríamos definir que nuestros perros **necesitan** un nombre para ser creados.\r\n**Si nosotros no definimos un constructor siempre tendrá uno vacío por defecto.\r\nSi en cambio definimos uno, se convertirá en obligatorio.**\r\n\r\n```csharp\r\npublic class Program\r\n{\r\n\tpublic static void Main(string[] args)\r\n\t{\r\n\t\tPerro miPrimerPerro = new Perro(\"Fido\"); //paso parametros distintos para asi tener 2 perros con distinto nombre\r\n\t\tPerro miSegundoPerro = new Perro(\"Firulais\");\r\n\t}\r\n}\r\n\r\npublic class Perro\r\n{\r\n\tpublic string nombre;\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\tpublic Perro(string nombreDelPerro)\r\n\t{\r\n\t\tnombre = nombreDelPerro; //asigno el parametro pasado por el constructor a la variable del objeto\r\n\t}\r\n\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n```\r\n\r\n### Diferencias entre clases y structs\r\n\r\n### Clases como tipos de referencia\r\n\r\nLas clases son denominadas **\"Reference Types\"** o **\"Tipos de Referencia\"**. Esto significa que las clases se manejan **por referencia**.\r\nLas variables de clases **guardan una referencia a un objeto. No guardan el objeto en sí. O sea, las variables guardan la información de donde se encuentra ese objeto en la memoria.**\r\nCuando utilizamos la palabra **new** seguida del constructor de la clase estamos creando un objeto en la memoria.\r\nLa variable involucrada, llamemosla **miReferencia**, guardará la dirección a donde se encuentra el objeto.\r\nSi nosotros luego asignamos a otra variable lo que **miReferencia** contiene, esta nueva variable también tendrá la dirección en memoria en donde se encuentra el objeto.\r\n**Pero el objeto siempre es el mismo. No se crean más objetos en el proceso, sino que se crean referencias a un sólo objeto.**\r\n\r\n**Cuando utilizamos el operador \".\" en una variable de clase, nos estamos refiriendo al objeto al que apuntan.**\r\n\r\n```csharp\r\npublic class Program\r\n{\r\n\tpublic static void Main(string[] args)\r\n\t{\r\n\t\t//Creo un objeto de perro, al usar la palabra \"new\"\r\n\t\tPerro miReferenciaAUnPerro = new Perro();\r\n\r\n\t\t//Al hacer esto las 2 variables pasan a \"apuntar\" al mismo objeto\r\n\t\t//Esto significa que podemos usar cualquiera de las 2 referencias para llamar\r\n\t\t//a métodos o variables de un mismo objeto\r\n\t\tPerro miOtraReferenciaAlMismoPerro = miReferenciaAUnPerro;\r\n\r\n\t\t//Cambio el nombre de mi perro con una de las referencias\r\n\t\tmiReferenciaAUnPerro.nombre = \"Firulais\";\r\n\r\n\t\t//Y puedo leerlo con cualquiera de ellas. No importa que referencia use aquí\r\n\t\t//En la consola siempre se mostrará \"Firulais\"\r\n\t\tConsole.WriteLine(miOtraReferenciaAlMismoPerro.nombre);\r\n\t}\r\n}\r\n\r\npublic class Perro\r\n{\r\n\tpublic string nombre;\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n```\r\n\r\nEsto es muy importante tenerlo en cuenta a la hora de pasar objetos a través de funciones como parámetros o devolviéndolos como resultado, con un return.\r\n\r\n```csharp\r\npublic class Program\r\n{\r\n\tpublic static void Main(string[] args)\r\n\t{\r\n\t\tPerro miReferenciaAUnPerro = new Perro();\r\n\r\n\t\tmiReferenciaAUnPerro.nombre = \"Firulais\";\r\n\r\n\t\tCambiarNombreAlPerro(miReferenciaAUnPerro);\r\n\r\n\t\t//Aquí será \"Hercules\" el resultado, porque el objeto fue\r\n\t\t//cambiado dentro del a función, a través de otra referencia\r\n\t\tConsole.WriteLine(miReferenciaAUnPerro.nombre);\r\n\t}\r\n\r\n\tstatic void CambiarNombreAlPerro(Perro unPerro)\r\n\t{\r\n\t\t//A pesar de que \"unPerro\" no es la misma variable que \"miReferenciaAUnPerro\"\r\n\t\t//estas apuntan al mismo objeto, así que puedo cambiar sus propiedades\r\n\t\t//desde cualquiera de ellas\r\n\t\tunPerro.nombre = \"Hercules\";\r\n\t}\r\n}\r\n\r\npublic class Perro\r\n{\r\n\tpublic string nombre;\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n```\r\n\r\n### Structs como tipos de valor\r\n\r\nLos structs, por el contrario que las clases, son **\"Value Types\"** o **\"Tipos de Valor\"**. Esto significa que los structs se manejan **por valor**.\r\nLas variables de structs **guardan el objeto en ellas, no una referencia**. Cuando asigno una variable de un struct a otra del mismo tipo **se crea un nuevo objeto del struct, una copia, y se asigna a la nueva variable.**\r\n\r\nVeamos los mismos ejemplos para \"Perro\", pero ahora como un struct.\r\n\r\n```csharp\r\npublic class Program\r\n{\r\n\tpublic static void Main(string[] args)\r\n\t{\r\n\t\t//Creo un objeto de perro, al usar la palabra \"new\"\r\n\t\tPerro miPerro = new Perro();\r\n\r\n\t\t//Le cambio el nombre a mi perro\r\n\t\tmiPerro.nombre = \"Firulais\";\r\n\r\n\t\t//Cuando asigno lo que hay en la primera variable a la segunda\r\n\t\t//el contenido se copia y se crea un nuevo objeto del struct\r\n\t\t//Esto significa que este segundo perro viene con el nombre \"Firulais\" también\r\n\t\tPerro miOtroPerro = miPerro;\r\n\r\n\t\t//Al cambiar el nombre del objeto de mi segunda variable de perro\r\n\t\t//cambio unicamente al perro que contiene \"miOtroPerro\"\r\n\t\tmiOtroPerro.nombre = \"Hercules\";\r\n\r\n\t\t//Ahora \"miOtroPerro\" se llama Hercules\r\n\t\t//y \"miPerro\" se sigue llamando Firulais\r\n\t\tConsole.WriteLine(miPerro.nombre);\r\n\t\tConsole.WriteLine(miOtroPerro.nombre);\r\n\t}\r\n}\r\n\r\npublic struct Perro\r\n{\r\n\tpublic string nombre;\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n```\r\n\r\n```csharp\r\npublic class Program\r\n{\r\n\tpublic static void Main(string[] args)\r\n\t{\r\n\t\tPerro miPerro = new Perro();\r\n\r\n\t\tmiPerro.nombre = \"Firulais\";\r\n\r\n\t\t//Al pasar un struct por una funcion, este tambien se copia\r\n\t\t//Por lo tanto, lo que reciba \"CambiarNombreAlPerro\" sera similar\r\n\t\t//pero no sera el mismo objeto que hay dentro de \"unPerro\"\r\n\t\tCambiarNombreAlPerro(miPerro);\r\n\t\t\r\n\t\t//\"miPerro\" se sigue llamando \"Firulais\"\r\n\t\t//su valor no cambio\r\n\t\tConsole.WriteLine(miPerro.nombre);\r\n\t}\r\n\r\n\tstatic void CambiarNombreAlPerro(Perro unPerro)\r\n\t{\r\n\t\t//Aunque el metodo diga que cambia el nombre del perro, esto no es cierto\r\n\t\t//porque \"unPerro\" es nuevo objeto de tipo Perro\r\n\t\t//Cuando se destruya el contexto de esta funcion\r\n\t\t//el objeto que tiene \"unPerro\" también lo hara\r\n\t\tunPerro.nombre = \"Hercules\";\r\n\t}\r\n}\r\n\r\npublic struct Perro\r\n{\r\n\tpublic string nombre;\r\n\tpublic const int cantidadDePatas = 4;\r\n\r\n\tpublic void Ladrar()\r\n\t{\r\n\t\tConsole.WriteLine(\"Guau!\");\r\n\t}\r\n}\r\n```\r\n\r\n\r\n\r\n## Pilares de la Programación Orientada a Objetos\r\n\r\n### Encapsulamiento\r\n\r\nEl encapsulamiento es la capacidad y práctica de ocultar la implementación de un objeto y obligar a que la utilización de este se realice mediante sus métodos públicos.\r\n\r\n#### Modificadores de Acceso\r\n\r\nLos modificadores de acceso determinan que clases pueden observar y utilizar los elementos de otras. Las variables y funciones que pertenecen a una clase tienen implícitamente modificadores de acceso.\r\nPor defecto, si no le coloca un modificador de acceso será **private**.\r\n\r\n#### Ejemplo:\r\n\r\n```csharp\r\npublic void UnaFuncionPublica()\r\n{\r\n\tConsole.WriteLine(\"Soy publica!\");\r\n}\r\n\r\nprivate string miVariablePrivada = \"Soy privada!\";\r\n```\r\n\r\nLos modificadores de acceso posibles son:\r\n\r\n- **public** -\u003e accesible desde cualquier clase.\r\n- **private** -\u003e accesible únicamente desde la clase que lo declara.\r\n- **protected** -\u003e accesible desde la clase que la declara y cualquier clase que herede de ella.\r\n- **internal** -\u003e accesible como si fuera pública desde el mismo assembly, \r\npero privada para otros assemeblies.\r\n- **protected internal** -\u003e accesible desde la clase que la declara y sus derivadas \r\ndentro del mismo assembly, pero privada para clases que hereden de la clase \r\nque la declara y se encuentren en otro assembly.\r\n- **private protected** -\u003e cuando un elemento tiene este modificador, las clases que hereden de \r\nla que lo declara heredarán este elemento y podrán acceder a el, pero no al mismo \r\nelemento perteneciente a otro objeto.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsammmte%2Fprogramacion-csharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsammmte%2Fprogramacion-csharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsammmte%2Fprogramacion-csharp/lists"}