
Hace unos días hablábamos de la serialización polimórfica en .NET 6, y vimos qué posibilidades teníamos para conseguirlo sin tener que escribir un custom converter o conversor personalizado. Y aunque realmente .NET 6 permite hacerlo, no es lo más elegante del mundo porque teníamos que operar sobre tipos object
.
Pero por suerte, en .NET 7 la cosa ha mejorado y ya tenemos opciones razonables para conseguirlo basadas en los dos nuevos atributos [JsonDerivedType]
y [JsonPolymorphic]
. Veamos cómo utilizarlos.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Un vistazo a los patrones relacionales y combinadores, lo nuevo de C# 9 para exprimir el pattern matching
José María Aguilar - El patrón Post-Redirect-Get
José María Aguilar
.NET Core / .NET
- Timers en .Net
Fernando Escolar - nameof get's a bit better in C# 12
Steven Giesel - How to Use SFTP For Secure File Upload in .NET
Code Maze - Getting .NET Library Projects to Output Dependent Assemblies
Rick Strahl - What's the latest .NET roadmap?
Steve Smith - Memory Allocation Optimization With BenchmarkDotNet
Code Maze - How to Convert a String to a Span in C#
Code Maze - Step-by-Step Guide to Adding and Removing Watermarks in PDF using C#
Sameerkhan - New Terminal logger for .NET 8
Steven Giesel - Raiders of the lost root: looking for memory leaks in .NET
Christophe Nasarre - VerificationException in .NET Framework when using structs
Kevin Gosse - .NET 7–Serialize private fields and properties
Bart Wullems - Implicit Operators in C# and How To Create a Multi Type
Nick Cosentino - .NET Micro-Optimization and Refactoring Trick
Patrick Smacchia

Imaginad una clase como la siguiente, que representa las características básicas de los archivos almacenados en una aplicación:
public class File
{
public string FileName { get; set; }
public ulong SizeBytes { get; set; }
}
Y ahora, imaginemos también una clase que hereda de la anterior para modelar específicamente, aunque también de forma resumida, los archivos de vídeo:
public class VideoFile: File
{
public string Codec { get; set; }
public TimeSpan Duration { get; set; }
}
Y puestos a imaginar, acabemos con el siguiente método, que retorna la representación JSON del objeto File
que recibe como parámetro:
string SerializeFile(File file) => JsonSerializer.Serialize(file);
Gracias al polimorfismo, ese pilar imprescindible de la Programación Orientada a Objetos, podríamos invocar este método con objetos de tipo File
, VideoFile
o cualquier descendiente de alguno de ambos, puesto que en todos los casos se trata de objetos de tipo File
:
var file = new File
{
FileName = "file.txt", SizeBytes = 1024
};
Console.WriteLine(SerializeFile(file));
var videoFile = new VideoFile
{
FileName = "video.mp4",
SizeBytes = 1024 * 1024,
Codec = "H264",
Duration = TimeSpan.FromMinutes(3)
};
Console.WriteLine(SerializeFile(videoFile));

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Inicializar a null propiedades sin tipo
José María Aguilar - Cómo saber si un objeto no es nulo (edición C# 9)
José María Aguilar
.NET Core / .NET
- Building a Dynamic Logical Expression Builder in C#
Yohan Malshika - Building Functional .NET Applications: a Guide for Choosing between Nahla Davies
- Detect Globalization-Invariant mode in .NET
Gérald Barré - Understanding the C# Init Operator
Bradley Wells - C# logging: Best practices in 2023 with examples and tools
Shane Duggan - How to Convert Stream to Byte Array in C#
Januarius Njoku - The Ultimate .NET Version Guide
Claudio Bernasconi - How to automatically update a Windows Forms Application?
Renato Ivanescu - .NET 7: Simplify Patch requests with PatchAsJsonAsync extension
Anthony Giretti - 6 useful extensions for IEnumerable
Steven Giesel - Understanding IOptions, IOptionsMonitor, and IOptionsSnapshot in .NET 7
Davide Bellone - Is WPF Dead? - The Current State of WPF [2023]
Claudio Bernasconi - Common C# exceptions and how to fix them
Carlos Schults - How does TryGetNonEnumeratedCount work?
Steven Giesel - How to Generate Permutations in C#
Matjaz Prtenjak - Refactor your .NET HTTP Clients to Typed HTTP Clients
Tim Deschryver - Feature toggle management in .NET Core
Krzysztof Begiedza - .NET Core–Monitor cache misses
Bart Wullems
Hace pocos meses hablábamos de la vuelta del clásico [OutputCache]
en ASP.NET Core 7 y veíamos cómo podía simplificarnos la vida a la hora de cachear en el servidor respuestas de peticiones.
Haciendo un rápido recordatorio, la novedad era la posibilidad de introducir en el pipeline el middleware OutputCacheMiddleware
, que se encargaría de almacenar las respuestas de endpoints y reutilizarlas en posteriores peticiones que cumplieran los requisitos apropiados.

Tras una semana de parón por una semanilla de relax en Roma (ciudad que, por cierto, os recomiendo que visitéis si no lo habéis hecho ya), ahí van los enlaces recopilados durante los últimos días. Como de costumbre, espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿Comprometidos o involucrados?
José María Aguilar - Crear bloques de código Razor reutilizables en Blazor con Render Fragments
José María Aguilar
.NET Core / .NET
- Top 5: Errores de performance en C#
Fernando Escolar - Announcing .NET 8 Preview 4
Jon Douglas - Serilog project update, May 2023
Nicholas Blumhardt - Control Visual Studio from an external application
Gérald Barré - Seamlessly Import and Export CSV Data in Excel Using C#
Mohan Chandran - Prevent .NET Application Insights telemetry loss
Anthony Simmon - Exploring Code Performance Testing in C# with BenchmarkDotNet
Kostis Grontis - Why do we need Wait() and Pulse() Methods in C# Threading?
Kulasangar Gowrisangar - Introduction - Rust for C#/.NET Developers
Atif Aziz et al - Upcoming availability of .NET Framework 4.8.1 on Windows Update and Catalog
Brett Lopez - Multidimensional Array vs Jagged Array in C#
Dusko Mirkovic - URI Encode and Decode in .NET
Code Maze - Concurrent Hosted Service Start and Stop in .NET 8
Steve Gordon - Hot Reload Supports Modifying Generics!
Mikelle Rogers - Client Support for Calling WCF/CoreWCF with System.ServiceModel 6.0 Is Here!
Sam Spencer - C# Tip: Advanced Switch Expressions and Switch Statements using filters
Davide Bellone - TaskCompletionSource Pitfalls
Stephan Gay - Struct vs. Record vs. Class in C#
A. Yohan Malshika - An alternative approach to structuring your tests in XUnit
Bart Wullems - Exploring the C# Source Link Feature: Enhancing Debugging Experiences
Neel Bhatt - XML Serialization in C# .NET Core: A Comprehensive Guide
Sanjay M.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Cómo mostrar por consola las líneas que se van añadiendo a logs o archivos de texto, en tiempo real
José María Aguilar - Métodos condicionales en .NET
José María Aguilar
.NET Core / .NET
- C# Record Type: Nondestructive Mutation, Equality, DTOs, and More
Bradley Wells - Verifying your DI Container
Steven Giesel - Reading Windows Application Manifest of an exe in .NET
Gérald Barré - Calling internal ctors in your unit tests”
Phil Haack - Using sizeof() Operator in C#
Code Maze - How to Create a Custom Slack Bot with .NET 7
Daniel Donbavand - How to convert audio to different formats using C# and FFmpeg
Niels Swimberghe - Dot Net Office : Top Microsoft NuGet Packages in 2023
Dot Net Office - Prevent a Hangfire job from running when it is already active
Tim Deschryver - Controlling the log level of your application
Steven Giesel

El 8 de mayo de 2006 decidí subir a un tren, teniendo más o menos clara la dirección, pero sin saber en qué parada me bajaría.
Cuando en aquél post inicial decía literalmente "espero que el viaje sea largo", probablemente no me refería a tan largo. Aún con la tenacidad de la que hacía gala, era imposible imaginar que diecisiete años después seguiría por aquí, contemplando el paisaje y escribiendo sobre lo que veo, intentando contribuir a una comunidad a la que tanto debo.
Más de 1.430 posts, más de 3.000 comentarios de lectores, más de cinco millones de consultas... pero sobre todo, muchísimo aprendido por el camino y, con suerte, espero que no solo por mi parte 😉

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Aspectos a tener en cuenta al crear sitios web públicos
José María Aguilar - Syncfusion Blazor UI components library: un primer vistazo
José María Aguilar
.NET Core / .NET
- Announcing .NET Community Toolkit 8.2! Faster generators, code fixers, performance improvements and more!
Sergio Pedri - C# 11 features I like the most
Neel Bhatt - How to Run an Async Method Synchronously in .NET
Code Maze - Deterministic Finalization in C#: IDisposable and Best Practices
Bradley Wells - A reminder to consider that your context, isn’t the only context (.NET 8 TimeProvider edition)
João Antunes - 10 Awesome C# Refactoring Tips
Assis Zang - Applying the decorator pattern in .NET Core using Castle.DynamicProxy
Bart Wullems - Some basic query support for System.Text.Json
Josef Ottosson

Atributos como [FromRoute]
, [FromForm]
, [FromQuery]
o [FromBody]
, entre otros, permiten ser muy precisos a la hora de indicar al framework cómo poblar los parámetros de los handlers de nuestros endpoints contruídos con Minimal APIs.
Por ejemplo, en la siguiente API sencilla se puede intuir que el parámetro id
del manejador será obtenido de la ruta, mientras que number
se obtendrá desde la query string:
app.MapPost("/friends/{id}/phones", ([FromRoute] int id, [FromQuery] string number) =>
{
// Añadir un número de teléfono al amigo
});
Y otro ejemplo, en el que usamos [FromBody]
para especificar que el parámetro de tipo Friend
queremos obtenerlo desde el cuerpo de la petición:
app.MapPut("/friends/{id}", ([FromRoute] int id, [FromBody] Friend friend) =>
{
// Actualizar amigo
});

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿Cuánto pesa realmente una aplicación Blazor WebAssembly recién creada?
José María Aguilar - Y todavía otras 101 citas célebres del mundo de la informática
José María Aguilar
.NET Core / .NET
- Trabajos en segundo plano en .Net
Fernando Escolar - Property Ordering in C# JSON Serialization
Code Maze - WireMock.NET - Troubleshooting
Cezary Piątek - Short Circuit Evaluation of IF Statements with Await in C#
Code Maze - Covariance and Contravariance in C#
Steven Giesel - Reduce Collection Lookups With ReSharper
Maarten Balliauw - Setting an Absolute Output Path for .NET SDK Projects
Rick Strahl

Versión tras versión, Entity Framework Core sigue introduciendo novedades que lo hacen cada vez más potente y atractivo para los desarrolladores. Sin ir más lejos, EF7, la última entrega disponible, incorporó bastantes mejoras en términos de rendimiento, soporte para columnas JSON, mapeo TPC, mapeo a procedimientos almacenados y muchas otras.
Pero una de las novedades que me resultó más interesante, quizás por ser muy esperada, fue la posibilidad de realizar borrados y actualizaciones de forma masiva sin tener que recurrir a lanzar directamente comandos SQL. O dicho de otra forma, con EF7 podremos ejecutar sentencias DELETE
y UPDATE
sobre la base de datos sin abandonar LINQ :)

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Palabras malditas
José María Aguilar - Analiza tu código a fondo y desde distintas perspectivas con NDepend
José María Aguilar
.NET Core / .NET
- Announcing .NET 8 Preview 3
Jiachen Jiang - Check out new C# 12 preview features!
Kathleen Dollard - Convert HTML to PDF Report in .NET
Abdul Rahman Shabeek Mohamed - How to Do an Inner Join in LINQ?
Code Maze - Run dotnet core projects without opening visual studio
Karthik Chintala - Investigating a crash in Enumerable.LastOrDefault with a custom collection
Gérald Barré - 5 useful extensions for Task<T> in .NET
Steven Giesel - Normalize and compare URLs with C#
Thomas Ardal - Using Application Insights in .NET Desktop Applications
Rick Strahl - Working With Nested Tasks
Pawel Woltschkow - Producing and Consuming Kafka Messages in CloudEvents Format Using the C# SDK
Vasil Kosturski - Why my WireMock mocks aren't working?
Daniel Genezini - C# Tip: Access items from the end of the array using the ^ operator
Davide Bellone - Static Fields Are Evil, If Not Coded Correctly
David McCarter - Upcasting and Downcasting in C#
Code Maze - .NET 8 Performance Edition
Steven Giesel - Converting Strings to .NET Objects – IParsable and ISpanParsable
Christian Nagel - Performance: The Fastest Way to Use Regular Expressions in Microsoft .NET 7
David McCarter - Different Ways to Split a String in C#
Code Maze - C#12 class and struct Primary Constructors
Patrick Smacchia

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- El hombre que inventó el Control-Alt-Suprimir
José María Aguilar - C# source generators: un ejemplo sencillo, paso a paso
José María Aguilar
.NET Core / .NET
- Looking at C# 12 Proposals and Beyond
Michael Shpilt - LINQ on steroids with SIMD
Steven Giesel - Does OpenTelemetry in .NET Cause Performance Degradation?
Martin J. T. - Refactoring Object-Orientation Abusers in C#
Code Maze - WireMock.NET - Introduction
Cezary Piątek - An abstract example of refactoring from interaction-based to property-based testing
Mark Seemann - How to Remove All Whitespace Characters From a String in C#?
Code Maze - Source Generators and Regular Expressions
Steven Giesel - Listing all available ETW events in a .NET application
Gérald Barré - Working with Tuple in C#
A. Yohan Malshika - C# 11.0 new features: Span<char> pattern matching
Ian Griffiths - Pythonnet – A Simple Union of .NET Core and Python You’ll Love
Nick Cosentino

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- C# Source generators: metaprogramación en tiempo de compilación
José María Aguilar - Desmitificando las expresiones lambda (I)
José María Aguilar
.NET Core / .NET
- How to create a NuGet metapackage
Daniel Wertheim - C# Source Generators: How to get build information?
Steven Giesel - Handling CancelKeyPress using a CancellationToken
Gérald Barré - Deep Copy of an Object in C#
Code Maze - Understanding the .NET ecosystem: The introduction of .NET Standard
Andrew Lock - Primary Constructors with C#
Christian Nagel - Improving multi-platform container support
Richard Lander - How to Delete Elements from an Array in C#
Code Maze - Using the contents of a file to define an MSBuild property
Raymond Chen - C# - Clean up your exception handling logic with Exception Filters
Bart Wullems - Using System.Text.Json to do polymorphic Json conversion in .NET 6
Allan Thraen - Observability in Wolverine
Jeremy D. Miller - Vendor-Agnostic Telemetry Using OpenTelemetry Collector in .NET
Phil Broderick - Change the ServiceLifetime after the service has been added to the .NET ServiceCollection
Niels Swimberghe

A raíz del artículo publicado hace algunas semanas sobre las ventajas de usar diccionarios en lugar de listas, me llegaba vía comentarios un escenario en el que se utilizaba una clase List<T>
para almacenar objetos a los que luego se accedía mediante clave. Lo diferencial del caso es que dichos objetos tenían varias claves únicas a través de las cuales podían ser localizados.
Por verlo por un ejemplo, el caso era más o menos como el que sigue:
public class FriendsCollection
{
private List<Friend> _friends = new();
...
public void Add(Friend friend)
{
_friends.Add(friend);
}
public Friend? GetById(int id)
=> _friends.FirstOrDefault(f => f.Id == id);
public Friend? GetByToken(string token)
=> _friends.FirstOrDefault(f => f.Token == token);
}
Obviamente en este escenario no podemos sustituir alegremente la lista por un diccionario, porque necesitamos acceder a los elementos usando dos claves distintas. Pero, por supuesto, podemos conseguir también la ansiada búsqueda O(1) si le echamos muy poquito más de tiempo.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Formas de relanzar excepciones en C#
José María Aguilar - Cómo crear bibliotecas de clases o proyectos de consola .NET 5 en lugar de .NET Core 3.1
José María Aguilar
.NET Core / .NET
- Adding Dependency Injection to a Console App in .Net 7
Paul Michaels - Loading RSA Keys in .NET & Loading RSA Keys in .NET
Scott Brady - How to Use MemoryStream in C#
Ivan Matec - Too many timers in .NET?
Gérald Barré - Implementing React's UseState in C#
Ricardo Peres - Understanding the .NET ecosystem: The evolution of .NET into .NET 7
Andrew Lock - Caching in .NET with MemoryCache
Steven Giesel - The Top .NET C# UI Controls You Should be Using
GrapeCity Developer Solutions - Iterator Benchmarks That Shocked With Unexpected Results
Nick Cosentino - .NET 8 Preview 2 Unveiled: 5 New Features You Need to Know
ByteHide - .NET Performance Delivers Again for Bing, From .NET 5 to .NET 7
Ben Watson - Secure your .NET cloud apps with rootless Linux Containers
Richard Lander - How to build a URL Shortener with C# .NET and Redis
Niels Swimberghe - .NET Core - Remove older SDKs and runtimes
Bart Wullems - How to Create a Custom JsonConverter in Json.NET
Ahsan Ullah - Leverage 'is not' Operator for Exception Filtering!
Steven Giesel

El pattern matching de C# proporciona la capacidad de analizar expresiones para ver si cumplen determinados "patrones" o presentan características determinadas. Podéis ver algunos ejemplos interesantes en el post Un vistazo a los patrones relacionales y combinadores.
Aunque ya los tengo bastante interiorizados y hago uso de ellos cuando toca, todavía no se me ha dado el caso de necesitar los patrones de listas, introducidos hace unos meses en C# 11. Así que no está de más echarles un vistazo para cuando se dé la ocasión 😉

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Radzen Blazor Components: ¡ahora open source!
José María Aguilar - Usando using, valga la redundancia (C#)
José María Aguilar
.NET Core / .NET
- Announcing .NET 8 Preview 2
Alexandra Barry - .NET 7 SDK built-in container improvements
Laurent Kempé - System.Text.Json Serializing Hierarchical Data
Christian Nagel - Partial Classes In C# And How to Use Them
Code Maze - Solving .NET JSON Deserialization Issues
Khalid Abuhakmeh - Using Trie Class for Efficient Text Pattern Searching in C#
Code Maze - How Async/Await Really Works in C#
Stephen Toub - Immutable Collections in C#
Code Maze - WkHtmlToPdf: Dealing with broken Url Encoded and Extended Character Links
Rick Strahl - Enhancing JPEG, PNG, Text Using C# .NET Part 1
GrapeCity Developer Solutions - Polly with .NET 6, Part 8 - Policy Registry with Minimal APIs, and HttpClientFactory
Bryan Hogan - Discover the New Features of .NET 8: What You Need to Know
ByteHide - Many Ways to make and Deserialize an HTTP GET with HttpClient
Bryan Hogan - Write your own AutoMapper in C#
Steven Giesel

A veces, los problemas de rendimiento de las aplicaciones, o determinadas funcionalidades de ellas, vienen derivados del uso de estructuras incorrectas para almacenar los datos, ya sea en memoria, base de datos o en cualquier tipo de almacén.
En este post vamos a centrarnos en un caso específico que me he encontrado demasiadas veces en código real: el uso indebido del tipo List<T>
cuando sólo nos interesa buscar en esta colección por una propiedad que actúa como identificador único del objeto T
.

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Si usas [EmailAddress] y [Url] para validar datos de entrada, ojo: ¡que hace tiempo que ya no validan mucho!
José María Aguilar - 101 formas de saber que tu proyecto está condenado al fracaso
José María Aguilar
.NET Core / .NET
- Gestionando la configuración de nuestras aplicaciones (1/x)
Sergio Navarro Pino - Delegados en C#
Benjamín Camacho - What's new for the WinForms Visual Basic Application Framework
Klaus Loeffelmann - Announcing ImageSharp 3.0.0
Siz Labors - We want your feedback! Introducing Polly v8
Joel Hulen - What really is the Entry Point of a .NET Module?
Washi - Understanding LINQ Deferred, Immediate, Streaming and Non-Streaming Executions
Abdul Rahman Shabeek Mohamed - .NET Console Application with injectable commands
Kees C. Bakker - Validating Connection Strings on .NET Startup
Khalid Abuhakmeh - Testing Roslyn Incremental Source Generators
Gérald Barré - How to Setup Integration Tests in .NET Without a WebApplicationFactory
Paul DeVito - How To Use The yield break Statement In C#?
Muhammed Saleem - How to Find the Caller Method in C#
Code Maze - Implementing the Producer Consumer Pattern with TPL Dataflow
Mark Heath - Alternative Way of Logging With OpenTelemetry Logging in .NET
Phil Broderick - Manipulating CSV Files in .NET
Assis Zang

Si desarrollas APIs, probablemente utilizarás Postman, Fiddler o herramientas similares para probarlas. Cualquier utilidad capaz de lanzar peticiones y analizar la respuesta, incluso basadas en línea de comandos como el desconocido Dotnet HTTP REPL, viene de perlas para ponernos en el lugar del cliente y comprobar cómo responde nuestra API ante determinados parámetros de entrada, o qué se siente al consumirla.
Tiempo atrás, el descubrimiento de la extensión REST client para Visual Studio Code supuso una bocanada de aire fresco en la forma de lanzar peticiones y examinar respuestas, para mi gusto mucho más cómoda que las que estaba acostumbrado a utilizar. Esta extensión permite definir peticiones HTTP en archivos de texto con extensión .http
o .rest
y ejecutarlas de forma realmente sencilla, sin abandonar el IDE.
Pues bien, la última revisión de Visual Studio 2022 (17.5) ha incluido el soporte nativo para este tipo de archivos, así que cada vez lo tenemos más sencillo. Y como es posible que alguno de vosotros aún no lo conozca, vamos a echarle un vistazo ;)

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Programadores con producción neta negativa (NNPP)
José María Aguilar - Trimming de espacios no significativos en Blazor 5
José María Aguilar
.NET Core / .NET
- Get Seamless Network Communication with These .NET Classes
Admir Mujkic - C# Tip: Initialize lists size to improve performance
Davide Bellone - How to Improve Enums With the SmartEnum Library
Code Maze - Extending the System Menu to add advanced commands in .NET
Gérald Barré - What To Be Wary of With Iterators and Collections in C#
Nick Cosentino - Raw Strings, UTF-8 Strings, and Multiline Interpolations – Using C# 11 in Rider and ReSharper
Sasha Ivanova - C# FileStream For Lazy Developers In A Hurry. The Bare Minimum
Gus Pear - Resiliency with Wolverine
Jeremy D. Miller - Speed Up ASP.NET Core JSON APIs with Source Generators
Khalid Abuhakmeh - IEnumerable, ICollection, IList and List
Code Maze - Write a high-quality README for NuGet packages
Lynn Dai - Microsoft Teams' Permission Service migration to .NET 6
Diogo Barbosa