CSharp

Tutorial CSharp: Variables y constantes

Aprende a declarar variables, constantes y gestionar el ámbito en C# para escribir código claro y eficiente. Guía completa para programadores.

Aprende CSharp y certifícate

Declaración de variables

En C#, las variables son espacios de memoria que utilizamos para almacenar datos durante la ejecución de nuestro programa. Antes de poder usar una variable, debemos declararla, indicando su tipo de dato y asignándole un nombre que nos permita referenciarla posteriormente.

Sintaxis básica

La sintaxis para declarar una variable en C# sigue este patrón:

tipoDeDato nombreVariable;

Donde tipoDeDato especifica qué clase de información almacenará la variable, y nombreVariable es el identificador que usaremos para referirnos a ella. Por ejemplo:

int edad;
string nombre;
bool estaActivo;

Inicialización de variables

Podemos declarar e inicializar una variable en una sola línea, asignándole un valor inicial:

int contador = 0;
string mensaje = "Hola mundo";
bool esValido = true;

También es posible declarar múltiples variables del mismo tipo en una sola línea:

int x = 10, y = 20, z = 30;

Convenciones de nomenclatura

En C#, se utiliza comúnmente la convención camelCase para nombrar variables:

int edadUsuario;
string nombreCompleto;
bool esAdministrador;

Es importante elegir nombres descriptivos que indiquen claramente el propósito de la variable:

// Poco descriptivo
int n;

// Descriptivo
int numeroDeEstudiantes;

Declaración implícita con var

C# permite la declaración implícita de variables utilizando la palabra clave var. El compilador infiere el tipo de dato basándose en el valor asignado:

var edad = 25;        // El compilador infiere que es un int
var nombre = "Ana";   // El compilador infiere que es un string
var activo = true;    // El compilador infiere que es un bool

Es importante entender que var no significa que la variable sea de tipo dinámico o que pueda cambiar de tipo. Una vez que el compilador infiere el tipo, este queda fijo:

var contador = 10;    // contador es de tipo int
contador = "texto";   // Error: no se puede asignar string a int

Declaración sin inicialización

Aunque podemos declarar variables sin inicializarlas, debemos asignarles un valor antes de usarlas:

int puntuacion;
// Código intermedio...
puntuacion = 100;     // Inicialización posterior

Si intentamos usar una variable no inicializada, obtendremos un error de compilación:

int valor;
int resultado = valor + 10;  // Error: variable no inicializada

Variables numéricas

Para variables numéricas, podemos usar diferentes tipos según el rango de valores que necesitemos:

byte pequeño = 255;           // 0 a 255
short corto = 32000;          // -32,768 a 32,767
int entero = 2000000;         // -2^31 a 2^31-1
long grande = 9000000000L;    // -2^63 a 2^63-1
float decimal1 = 3.14f;       // Precisión de 7 dígitos
double decimal2 = 3.14159265; // Precisión de 15-16 dígitos
decimal precio = 29.99m;      // Precisión de 28-29 dígitos

Variables de texto

Para almacenar texto, utilizamos principalmente dos tipos:

char letra = 'A';             // Un solo carácter Unicode
string texto = "Hola mundo";  // Cadena de caracteres

Variables booleanas

Para representar valores de verdadero o falso:

bool esCorrecto = true;
bool tienePermiso = false;

Declaración de variables con valores predeterminados

Podemos inicializar variables con valores predeterminados usando la sintaxis de inicialización por defecto:

int numero = default;         // 0
string texto = default;       // null
bool bandera = default;       // false

O de forma más explícita:

int contador = default(int);  // 0

Declaración de variables con literales numéricos

C# permite usar separadores de dígitos (guiones bajos) para mejorar la legibilidad de números grandes:

int millón = 1_000_000;
long billón = 1_000_000_000_000L;

También podemos usar prefijos para especificar la base numérica:

int binario = 0b1010_1100;    // Binario (prefijo 0b)
int hexadecimal = 0xABCD;     // Hexadecimal (prefijo 0x)

Consideraciones importantes

  • Los nombres de variables en C# son sensibles a mayúsculas y minúsculas, por lo que contador y Contador serían variables diferentes.
  • No se pueden usar palabras reservadas de C# como nombres de variables (por ejemplo, int, string, class).
  • Las variables deben tener nombres que comiencen con una letra o un guion bajo, no con un número.
  • Es una buena práctica inicializar las variables al declararlas para evitar errores por valores no asignados.

La declaración adecuada de variables es fundamental para escribir código claro y mantenible, ya que establece la base para el manejo de datos en nuestros programas.

Uso de constantes

Las constantes en C# son valores que, una vez asignados, no pueden modificarse durante la ejecución del programa. A diferencia de las variables, cuyo contenido puede cambiar, las constantes mantienen su valor inicial a lo largo de toda la vida de la aplicación. Esto las hace ideales para representar valores fijos que no deberían alterarse.

Declaración de constantes con const

Para declarar una constante en C#, utilizamos la palabra clave const antes del tipo de dato:

const int MaximoIntentos = 3;
const double Pi = 3.14159265359;
const string MensajeBienvenida = "Bienvenido a la aplicación";

Al declarar una constante, es obligatorio asignarle un valor en la misma línea de la declaración. No es posible declarar una constante sin inicializarla:

const int LimiteEdad;  // Error: las constantes deben inicializarse

Convenciones de nomenclatura

Para las constantes en C#, se utiliza comúnmente la convención PascalCase (primera letra de cada palabra en mayúscula):

const int ValorMaximo = 100;
const string NombreEmpresa = "MiCompañía";

Esta convención ayuda a distinguir visualmente las constantes de las variables regulares, que normalmente usan camelCase.

Tipos de datos permitidos

Las constantes pueden ser de cualquier tipo de dato primitivo como int, double, bool, char o string:

const int DiasEnSemana = 7;
const double GravedadTierra = 9.81;
const bool EsProduccion = false;
const char Separador = ';';
const string Version = "1.0.0";

Sin embargo, hay una limitación importante: el valor de una constante debe ser determinado en tiempo de compilación. Esto significa que no podemos asignar a una constante el resultado de una llamada a un método o cualquier otra operación que se resuelva en tiempo de ejecución:

const double Aleatorio = Math.Random();  // Error: no se puede resolver en compilación
const string FechaActual = DateTime.Now.ToString();  // Error

Constantes vs variables de solo lectura

Si necesitamos una constante cuyo valor se determine en tiempo de ejecución, podemos usar una variable de solo lectura con la palabra clave readonly:

readonly double ValorCalculado;

// En un constructor:
public MiClase()
{
    ValorCalculado = Math.Sqrt(16);  // Permitido en readonly
}

La principal diferencia es que readonly permite la asignación en el constructor, mientras que const requiere un valor en tiempo de compilación.

Constantes en diferentes ámbitos

Las constantes pueden declararse a nivel de clase o dentro de métodos:

// A nivel de clase
public class Configuracion
{
    const int TiempoEspera = 30;
    
    public void Metodo()
    {
        // A nivel de método
        const string Prefijo = "CFG_";
        
        // Uso de ambas constantes
        Console.WriteLine($"{Prefijo}{TiempoEspera}");
    }
}

Uso de constantes para mejorar el código

Las constantes ayudan a crear código más mantenible y legible:

// Sin constantes (números mágicos)
if (edad < 18)
{
    Console.WriteLine("No tiene edad suficiente");
}

// Con constantes (más legible)
const int EdadMinima = 18;
if (edad < EdadMinima)
{
    Console.WriteLine("No tiene edad suficiente");
}

También facilitan los cambios globales, ya que solo necesitamos modificar el valor en un lugar:

// Si cambiamos la edad mínima a 21, solo modificamos la constante
const int EdadMinima = 21;

Constantes en expresiones

Las constantes pueden utilizarse en expresiones para crear otras constantes, siempre que la expresión completa pueda evaluarse en tiempo de compilación:

const int HorasPorDia = 24;
const int MinutosPorHora = 60;
const int SegundosPorMinuto = 60;
const int SegundosPorDia = HorasPorDia * MinutosPorHora * SegundosPorMinuto;

Constantes vs enumeraciones

Para grupos de constantes relacionadas, las enumeraciones suelen ser más apropiadas:

// En lugar de múltiples constantes
const int DiaSemanaLunes = 1;
const int DiaSemanaMiercoles = 3;

// Es mejor usar una enumeración
enum DiaSemana
{
    Lunes = 1,
    Martes = 2,
    Miercoles = 3,
    Jueves = 4,
    Viernes = 5,
    Sabado = 6,
    Domingo = 7
}

Constantes para configuración

Las constantes son ideales para valores de configuración que no cambiarán durante la ejecución:

public class ConfiguracionApp
{
    public const string RutaArchivosLog = "C:\\Logs\\";
    public const int TiempoSesionMinutos = 30;
    public const bool ModoDebug = false;
}

// Uso desde cualquier parte del código
string rutaCompleta = ConfiguracionApp.RutaArchivosLog + "error.log";

Consideraciones de rendimiento

El uso de constantes puede mejorar ligeramente el rendimiento, ya que el compilador puede realizar optimizaciones al conocer los valores en tiempo de compilación. Además, las constantes no ocupan espacio en memoria por cada instancia de la clase, a diferencia de los campos normales.

Ámbito (scope)

El ámbito o scope en C# define la región del código donde una variable es accesible y puede ser utilizada. Entender correctamente el ámbito de las variables es fundamental para escribir código organizado y evitar errores comunes relacionados con la visibilidad de los datos.

Ámbito de bloque

En C#, un bloque de código está delimitado por llaves {}. Las variables declaradas dentro de un bloque solo son accesibles dentro de ese bloque y sus bloques anidados:

{
    int x = 10; // Variable con ámbito limitado a este bloque
    Console.WriteLine(x); // Correcto: x es accesible aquí
}
// Console.WriteLine(x); // Error: x no existe fuera del bloque

Este concepto es especialmente importante en estructuras como condicionales y bucles:

if (true)
{
    int contador = 1; // Variable local al bloque if
    Console.WriteLine(contador);
}
// contador no existe aquí

Ámbito de método

Las variables declaradas dentro de un método solo son visibles dentro de ese método:

void MiMetodo()
{
    int valor = 5; // Variable con ámbito limitado a MiMetodo
    Console.WriteLine(valor);
}

void OtroMetodo()
{
    // Console.WriteLine(valor); // Error: valor no es accesible aquí
}

Esto permite que diferentes métodos utilicen el mismo nombre de variable sin conflictos, ya que cada variable existe solo en su propio ámbito:

void PrimerMetodo()
{
    int contador = 1; // Esta variable solo existe en PrimerMetodo
}

void SegundoMetodo()
{
    int contador = 100; // Esta es una variable diferente
}

Ámbitos anidados

Cuando tenemos bloques anidados, las variables de un ámbito exterior son accesibles desde ámbitos interiores:

void EjemploAmbitos()
{
    int exterior = 10; // Variable en el ámbito del método
    
    {
        int interior = 20; // Variable en un ámbito anidado
        Console.WriteLine(exterior); // Correcto: podemos acceder a 'exterior'
        Console.WriteLine(interior); // Correcto: podemos acceder a 'interior'
    }
    
    Console.WriteLine(exterior); // Correcto: 'exterior' sigue siendo accesible
    // Console.WriteLine(interior); // Error: 'interior' no existe en este ámbito
}

Ocultamiento de variables

Si declaramos una variable con el mismo nombre en un ámbito interior, esta oculta a la variable del ámbito exterior:

void EjemploOcultamiento()
{
    int valor = 5; // Variable en el ámbito del método
    
    {
        int valor = 10; // Nueva variable que oculta a la exterior
        Console.WriteLine(valor); // Muestra 10
    }
    
    Console.WriteLine(valor); // Muestra 5
}

Aunque esta práctica es técnicamente válida, se considera confusa y propensa a errores, por lo que es mejor evitarla usando nombres diferentes.

Ámbito en estructuras de control

Las estructuras de control como if, for, while y switch crean sus propios ámbitos:

// Ámbito en if
if (true)
{
    int resultado = 42;
    Console.WriteLine(resultado);
}
// resultado no existe aquí

// Ámbito en for
for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}
// i no existe aquí

// Ámbito en while
int contador = 0;
while (contador < 3)
{
    string mensaje = "Iteración " + contador;
    Console.WriteLine(mensaje);
    contador++;
}
// mensaje no existe aquí, pero contador sí

En el caso de los bucles for, la variable de control (como i en el ejemplo) solo existe dentro del ámbito del bucle.

Declaración de variables en el punto de uso

Una buena práctica en C# es declarar las variables lo más cerca posible de donde se utilizan por primera vez, limitando su ámbito al mínimo necesario:

void ProcesarDatos()
{
    // Declarar variables solo cuando se necesitan
    int primerValor = 10;
    Console.WriteLine(primerValor);
    
    // Más código...
    
    // Declarar otra variable más adelante cuando se necesita
    int segundoValor = 20;
    Console.WriteLine(segundoValor);
}

Esto mejora la legibilidad del código y reduce la posibilidad de errores al limitar el ámbito de las variables.

Variables con el mismo nombre en diferentes ámbitos

Es posible tener variables con el mismo nombre en diferentes ámbitos sin que haya conflicto:

void Metodo1()
{
    int contador = 1;
    // Este contador solo existe en Metodo1
}

void Metodo2()
{
    int contador = 100;
    // Este es un contador diferente que solo existe en Metodo2
}

Ámbito de variables en instrucciones using

C# permite declarar variables directamente en instrucciones using para gestionar recursos. Estas variables tienen un ámbito limitado al bloque using:

void LeerArchivo()
{
    using (var archivo = new System.IO.StreamReader("archivo.txt"))
    {
        string contenido = archivo.ReadToEnd();
        Console.WriteLine(contenido);
    }
    // archivo y contenido no existen fuera del bloque using
}

Ámbito en instrucciones switch

En las instrucciones switch, cada caso crea su propio ámbito:

void EjemploSwitch(int opcion)
{
    switch (opcion)
    {
        case 1:
            int valor = 10;
            Console.WriteLine(valor);
            break;
        case 2:
            int valor = 20; // Válido porque es un ámbito diferente
            Console.WriteLine(valor);
            break;
    }
}

Ámbito y shadowing en bucles foreach

En los bucles foreach, la variable de iteración tiene un ámbito limitado al cuerpo del bucle:

void ProcesarElementos()
{
    int[] numeros = { 1, 2, 3 };
    
    foreach (int numero in numeros)
    {
        Console.WriteLine(numero);
    }
    // numero no existe aquí
}

Consideraciones prácticas

  • Minimizar el ámbito: Limita el ámbito de tus variables lo máximo posible para reducir la complejidad del código.
  • Evitar nombres duplicados: Aunque C# permite tener variables con el mismo nombre en diferentes ámbitos, esto puede generar confusión.
  • Declaración en el punto de uso: Declara las variables justo antes de usarlas, no al principio del método.
  • Bloques explícitos: Usa bloques con llaves {} para definir claramente los ámbitos, incluso cuando son opcionales (como en if de una sola línea).

Entender correctamente el ámbito de las variables te ayudará a escribir código más limpio, evitar errores de acceso a datos y mejorar la organización de tu programa.

Aprende CSharp online

Otras lecciones de CSharp

Accede a todas las lecciones de CSharp y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A C#

Introducción Y Entorno

Creación De Proyecto C#

Introducción Y Entorno

Variables Y Constantes

Sintaxis

Tipos De Datos

Sintaxis

Operadores

Sintaxis

Control De Flujo

Sintaxis

Funciones

Sintaxis

Estructuras De Control Iterativo

Sintaxis

Interpolación De Strings

Sintaxis

Estructuras De Control Condicional

Sintaxis

Manejo De Valores Nulos

Sintaxis

Clases Y Encapsulación

Programación Orientada A Objetos

Objetos

Programación Orientada A Objetos

Constructores Y Destructores

Programación Orientada A Objetos

Herencia

Programación Orientada A Objetos

Polimorfismo

Programación Orientada A Objetos

Genéricos

Programación Orientada A Objetos

Métodos Virtuales Y Sobrecarga

Programación Orientada A Objetos

Clases Abstractas

Programación Orientada A Objetos

Interfaces

Programación Orientada A Objetos

Propiedades Y Encapsulación

Programación Orientada A Objetos

Métodos De Extensión

Programación Orientada A Objetos

Clases Y Objetos

Programación Orientada A Objetos

Clases Parciales

Programación Orientada A Objetos

Miembros Estáticos

Programación Orientada A Objetos

Tuplas Y Tipos Anónimos

Programación Orientada A Objetos

Arrays Y Listas

Colecciones Y Linq

Diccionarios

Colecciones Y Linq

Conjuntos, Colas Y Pilas

Colecciones Y Linq

Uso De Consultas Linq

Colecciones Y Linq

Linq Avanzado

Colecciones Y Linq

Colas Y Pilas

Colecciones Y Linq

Conjuntos

Colecciones Y Linq

Linq Básico

Colecciones Y Linq

Delegados Funcionales

Programación Funcional

Records

Programación Funcional

Expresiones Lambda

Programación Funcional

Linq Funcional

Programación Funcional

Fundamentos De La Programación Funcional

Programación Funcional

Pattern Matching

Programación Funcional

Testing Unitario Con Xunit

Testing

Excepciones

Excepciones

Delegados

Programación Asíncrona

Eventos

Programación Asíncrona

Lambdas

Programación Asíncrona

Uso De Async Y Await

Programación Asíncrona

Tareas

Programación Asíncrona

Accede GRATIS a CSharp y certifícate

Ejercicios de programación de CSharp

Evalúa tus conocimientos de esta lección Variables y constantes con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender cómo declarar e inicializar variables en C#.
  • Diferenciar entre variables y constantes, y conocer sus usos y limitaciones.
  • Aplicar las convenciones de nomenclatura adecuadas para variables y constantes.
  • Entender el concepto de ámbito (scope) y cómo afecta la visibilidad de las variables.
  • Reconocer buenas prácticas para la declaración y manejo de variables en diferentes contextos.