Funcional vs POO en C#: ¿qué elegir en 2025?

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: dos caras de la misma moneda

\n\n

Imagina que estás construyendo una casa. Puedes tomar bloques prefabricados (clases, objetos, herencia) y ensamblarlos en una estructura compleja — esto es la programación orientada a objetos (POO). O puedes pensar como un matemático: "tomo datos, les aplico una función pura y obtengo un nuevo resultado, sin cambiar nada" — esto es la programación funcional.

\n\n

En C# ambas paradigmas conviven de manera sorprendente. Y si escribes en este lenguaje, tarde o temprano te preguntarás: "¿Y si lo estoy haciendo mal? ¿Quizás debería usar más LINQ y menos clases?"

\n\n

En este artículo no discutiremos qué es mejor. Analizaremos en qué se diferencia el enfoque funcional de la POO en C#, cuándo cada uno realmente ayuda y cuándo perjudica. Y sí, habrá mucho código. ¡Allá vamos!

\n\n

1. POO en C#: lo clásico que funciona

\n\n

La programación orientada a objetos trata sobre el estado y el comportamiento. Tienes una clase que almacena datos (campos, propiedades) y métodos que modifican esos datos.

\n\n

Ejemplo: una aplicación para gestionar pedidos en una tienda online.

\n\n
public class Order\n{\n    public int Id { get; set; }\n    public List<string> Items { get; private set; }\n    public decimal TotalPrice { get; private set; }\n\n    public Order(int id)\n    {\n        Id = id;\n        Items = new List<string>();\n        TotalPrice = 0;\n    }\n\n    public void AddItem(string itemName, decimal price)\n    {\n        Items.Add(itemName);\n        TotalPrice += price;\n    }\n\n    public void ApplyDiscount(decimal percent)\n    {\n        TotalPrice -= TotalPrice * (percent / 100);\n    }\n}
\n\n

¿Qué vemos? Encapsulación: TotalPrice no se puede modificar directamente, solo a través de métodos. Estado del objeto cambia con el tiempo: agregamos productos, aplicamos descuentos. Esto es POO pura.

\n\n

Ventajas de la POO en C#

\n
    \n
  • Modelo comprensible del mundo real: Pedido, Cliente, Producto — todo como en la vida real.
  • \n
  • Reutilización mediante herencia e interfaces.
  • \n
  • Gestión de la complejidad dividiendo en objetos pequeños.
  • \n
\n\n

Desventajas de la POO

\n
    \n
  • Efectos secundarios: un método puede cambiar el estado y fácilmente pierdes el control.
  • \n
  • Dificultad para probar: hay que crear objetos, simular dependencias.
  • \n
  • Redundancia: a veces es más fácil escribir una función que crear toda una clase.
  • \n
\n\n

2. Enfoque funcional en C#: LINQ y más

\n\n

La programación funcional trata sobre funciones puras (sin efectos secundarios) y la inmutabilidad de los datos. En C# esto es especialmente notable en LINQ, expresiones lambda y el trabajo con colecciones.

\n\n

Resolvamos la misma tarea — gestionar un pedido — pero de forma funcional.

\n\n
// Registro inmutable (record)\npublic record Order(int Id, List<string> Items, decimal TotalPrice);\n\npublic static class OrderFunctions\n{\n    public static Order AddItem(Order order, string item, decimal price)\n    {\n        var newItems = order.Items.Append(item).ToList();\n        return order with { Items = newItems, TotalPrice = order.TotalPrice + price };\n    }\n\n    public static Order ApplyDiscount(Order order, decimal percent)\n    {\n        return order with { TotalPrice = order.TotalPrice * (1 - percent / 100) };\n    }\n}\n\n// Uso\nvar order = new Order(1, new List<string>(), 0);\norder = OrderFunctions.AddItem(order, "Portátil", 50000);\norder = OrderFunctions.ApplyDiscount(order, 10);
\n\n

¿Te diste cuenta? No modificamos el objeto original. Cada vez se crea una nueva instancia con with. Esto elimina cambios accidentales.

\n\n

Y

Blogs

Book Recommendations