¿Por qué C# no es solo para «corporativos» y aburrimiento?
\n\nEn el mundo de la TI existe un estereotipo: C# es un lenguaje para proyectos empresariales aburridos, sistemas bancarios y portales de servicios gubernamentales. Pero si dejamos de lado los prejuicios, descubriremos que en C# están escritos Stack Overflow, Unity, parte de Visual Studio e incluso JetBrains Rider. Analicemos casos reales de empresas que utilizan C# en producción y veamos el código que hay detrás.
\n\nEste artículo no es teoría seca, sino un análisis de proyectos reales con ejemplos que podrá adaptar a sus propias tareas. ¡Empecemos!
\n\nCaso 1: Stack Overflow — cómo C# soporta 1 mil millones de solicitudes al mes
\n\nStack Overflow es, probablemente, el ejemplo más conocido del uso de C# en un proyecto de alta carga. El sitio procesa más de 1 mil millones de visitas a páginas al mes y funciona con ASP.NET MVC (ahora .NET Core) utilizando Redis y Elasticsearch.
\n\nArquitectura y ¿por qué C#?
\nEl equipo de Stack Overflow eligió C# por su rendimiento, tipado estricto y excelente soporte para la concurrencia. La clave está en el uso mínimo de bibliotecas de terceros. Ellos mismos escribieron su propio ORM (Dapper) y su propia capa de caché.
\n\nEjemplo de código: caché de alto rendimiento con Redis
\nUno de los secretos de la velocidad de Stack Overflow es el almacenamiento en caché agresivo. Así es más o menos como se ve su enfoque para trabajar con Redis a través de StackExchange.Redis:
public class CacheService\n{\n private readonly IDatabase _cache;\n private readonly TimeSpan _defaultExpiry = TimeSpan.FromMinutes(10);\n\n public CacheService(IConnectionMultiplexer redis)\n {\n _cache = redis.GetDatabase();\n }\n\n public async Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> factory)\n {\n // Intento de obtener desde la caché\n var cached = await _cache.StringGetAsync(key);\n if (cached.HasValue)\n {\n return JsonSerializer.Deserialize<T>(cached);\n }\n\n // Si no está, llamamos a la fábrica y lo guardamos\n var value = await factory();\n var serialized = JsonSerializer.Serialize(value);\n await _cache.StringSetAsync(key, serialized, _defaultExpiry);\n return value;\n }\n}\n\n\n¿Por qué es genial? No solo almacenan en caché todo sin criterio: utilizan el patrón cache-aside y establecen un TTL (tiempo de vida) según el tipo de datos. Por ejemplo, para la lista de preguntas — 30 segundos, para el perfil de usuario — 5 minutos.
\n\nCaso 2: Unity — C# como lenguaje para juegos y 3D
\n\nUnity es el motor de juegos principal para desarrolladores independientes y grandes estudios. Internamente está escrito en C++ (núcleo), pero todo el scripting para juegos es en C#. Más del 50% de los juegos móviles del mundo están hechos con Unity, y no solo «Angry Birds», sino también Hearthstone o Pokémon GO.
\n\n¿Por qué C# y no C++?
\nUnity eligió C# por el equilibrio: es más rápido que Python o JavaScript, pero más seguro y sencillo que C++. El recolector de basura (GC) puede ser un problema, pero en Unity han aprendido a controlarlo.
\n\nEjemplo de código: optimización mediante un pool de objetos
\nEn los juegos, a menudo se crean y destruyen objetos (balas, enemigos, partículas). Para evitar tirones debido al GC, se utiliza un Object Pool. Así es como se ve en C#:
\n\npublic class BulletPool : MonoBehaviour\n{\n private Queue<Bullet> _pool = new Queue<Bullet>();\n [SerializeField] private Bullet _bulletPrefab;\n\n public Bullet Get()\n {\n if (_pool.Count > 0)\n {\n var bullet = _pool.Dequeue();\n bullet.gameObject.SetActive(true);\n return bullet;\n }\n return Instantiate(_bulletPrefab);\n }\n\n public void Return(Bullet bullet)\n {\n bullet.gameObject.SetActive(fa