{"id":1257,"date":"2026-03-12T08:57:45","date_gmt":"2026-03-12T11:57:45","guid":{"rendered":"https:\/\/maurobernal.com.ar\/blog\/?p=1257"},"modified":"2026-03-12T08:57:45","modified_gmt":"2026-03-12T11:57:45","slug":"csharp-13-params-span-lock-task-wheneach-dotnet9","status":"publish","type":"post","link":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/","title":{"rendered":"C# 13: params modernos, Lock de primera clase y Task.WhenEach"},"content":{"rendered":"\n<p class=\"intro-destacado\">C# 13 con .NET 9 lleg\u00f3 con mejoras que parecen peque\u00f1as pero cambian patrones que usamos hace a\u00f1os. Los params con Span eliminan allocations que ni sab\u00edamos que est\u00e1bamos haciendo. El Lock de primera clase hace que el threading sea m\u00e1s seguro. Y Task.WhenEach resuelve un patr\u00f3n as\u00edncrono que antes requer\u00eda c\u00f3digo contorsionado.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">params ReadOnlySpan&lt;T&gt;: cero allocations en m\u00e9todos vari\u00e1dicos<\/h2>\n\n\n\n<p>Antes de C# 13, <code>params<\/code> solo funcionaba con arrays. Cada vez que llamabas a un m\u00e9todo con <code>params int[]<\/code>, el compilador creaba un array en el heap aunque los datos pudieran vivir perfectamente en el stack. C# 13 cambia eso.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code\">\/\/ &#x274c; C# 12 y anteriores: params siempre crea un array en el heap\npublic static int Sumar(params int[] numeros)\n{\n    int total = 0;\n    foreach (var n in numeros) total += n;\n    return total;\n}\n\n\/\/ Cada llamada alloca un int[] en el heap:\nint r1 = Sumar(1, 2, 3);      \/\/ new int[] { 1, 2, 3 }\nint r2 = Sumar(10, 20);        \/\/ new int[] { 10, 20 }\n\n\/\/ &#x2705; C# 13: params con ReadOnlySpan \u2014 cero allocations\npublic static int Sumar(params ReadOnlySpan&lt;int&gt; numeros)\n{\n    int total = 0;\n    foreach (var n in numeros) total += n;\n    return total;\n}\n\n\/\/ El compilador puede poner los valores directamente en el stack\nint r1 = Sumar(1, 2, 3);   \/\/ Sin heap allocation\nint r2 = Sumar(10, 20);     \/\/ Sin heap allocation\n\n\/\/ Tambi\u00e9n funciona con otros tipos de colecci\u00f3n\npublic static void LogTodos(params IEnumerable&lt;string&gt; mensajes) { ... }\npublic static T Primero&lt;T&gt;(params ReadOnlySpan&lt;T&gt; items) =&gt; items[0];<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">System.Threading.Lock: el tipo de primera clase para sincronizaci\u00f3n<\/h2>\n\n\n\n<p>Durante a\u00f1os, el patr\u00f3n est\u00e1ndar para sincronizar hilos en C# era <code>lock (new object())<\/code>. Funcionaba, pero ten\u00eda un problema: <code>object<\/code> no comunica la intenci\u00f3n. Cualquier referencia pod\u00eda usarse accidentalmente como lock. <code>System.Threading.Lock<\/code> resuelve eso con un tipo dedicado que el compilador trata de forma especial.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code\">\/\/ &#x274c; Antes: object gen\u00e9rico como lock\npublic class Cache\n{\n    private readonly object _lock = new object();\n    private Dictionary&lt;string, object&gt; _datos = new();\n\n    public void Agregar(string clave, object valor)\n    {\n        lock (_lock)\n        {\n            _datos[clave] = valor;\n        }\n    }\n\n    public bool TryGet(string clave, out object? valor)\n    {\n        lock (_lock)\n        {\n            return _datos.TryGetValue(clave, out valor);\n        }\n    }\n}\n\n\/\/ &#x2705; C# 13 \/ .NET 9: System.Threading.Lock\npublic class Cache\n{\n    \/\/ Sem\u00e1nticamente claro: esto ES un lock, no cualquier objeto\n    private readonly Lock _lock = new();\n    private Dictionary&lt;string, object&gt; _datos = new();\n\n    public void Agregar(string clave, object valor)\n    {\n        \/\/ El compilador emite c\u00f3digo optimizado para Lock\n        \/\/ Usa el patr\u00f3n Dispose internamente (EnterScope)\n        lock (_lock)\n        {\n            _datos[clave] = valor;\n        }\n    }\n\n    \/\/ Tambi\u00e9n disponible: API expl\u00edcita para casos avanzados\n    public bool TryAgregar(string clave, object valor)\n    {\n        using (_lock.EnterScope())\n        {\n            if (_datos.ContainsKey(clave)) return false;\n            _datos[clave] = valor;\n            return true;\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p>El compilador emite una advertencia si intent\u00e1s pasar un <code>Lock<\/code> como <code>object<\/code> a otro m\u00e9todo \u2014 protecci\u00f3n contra el antipatr\u00f3n de usar el mismo lock para m\u00faltiples prop\u00f3sitos.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Task.WhenEach: procesar tareas a medida que terminan<\/h2>\n\n\n\n<p>Ten\u00eda un patr\u00f3n que repet\u00eda en muchos proyectos: lanzar varias tareas en paralelo y procesar cada resultado apenas llegaba, sin esperar a que todas terminen. Antes requer\u00eda <code>Task.WhenAny<\/code> en un loop con manejo manual. <code>Task.WhenEach<\/code> lo vuelve trivial.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code\">\/\/ &#x274c; Antes: patr\u00f3n verbose con Task.WhenAny\nvar tareas = new List&lt;Task&lt;Reporte&gt;&gt; { \n    ObtenerReporteAsync(\"ventas\"), \n    ObtenerReporteAsync(\"stock\"), \n    ObtenerReporteAsync(\"clientes\") \n};\n\nvar pendientes = new HashSet&lt;Task&lt;Reporte&gt;&gt;(tareas);\nwhile (pendientes.Count &gt; 0)\n{\n    var completada = await Task.WhenAny(pendientes);\n    pendientes.Remove(completada);\n    var reporte = await completada;\n    Console.WriteLine($\"Reporte listo: {reporte.Nombre}\");\n}\n\n\/\/ &#x2705; C# 13 \/ .NET 9: Task.WhenEach \u2014 elegante y eficiente\nvar tareas = new List&lt;Task&lt;Reporte&gt;&gt; { \n    ObtenerReporteAsync(\"ventas\"), \n    ObtenerReporteAsync(\"stock\"), \n    ObtenerReporteAsync(\"clientes\") \n};\n\nawait foreach (var completada in Task.WhenEach(tareas))\n{\n    var reporte = await completada;\n    Console.WriteLine($\"Reporte listo: {reporte.Nombre}\");\n    \/\/ Procesa cada reporte apenas llega, sin bloquear a los dem\u00e1s\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">LINQ: CountBy, AggregateBy e Index<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code\">var pedidos = new[] {\n    new { Cliente = \"Ana\",  Monto = 100m },\n    new { Cliente = \"Juan\", Monto = 200m },\n    new { Cliente = \"Ana\",  Monto = 150m },\n    new { Cliente = \"Juan\", Monto = 300m },\n};\n\n\/\/ CountBy: contar elementos agrupados por clave\nvar pedidosPorCliente = pedidos.CountBy(p =&gt; p.Cliente);\n\/\/ { \"Ana\": 2, \"Juan\": 2 }\n\n\/\/ AggregateBy: acumular valores agrupados por clave\nvar totalPorCliente = pedidos.AggregateBy(\n    p =&gt; p.Cliente,\n    seed: 0m,\n    (acum, p) =&gt; acum + p.Monto\n);\n\/\/ { \"Ana\": 250, \"Juan\": 500 }\n\n\/\/ Index(): obtener \u00edndice sin usar Select((x, i) => ...)\nforeach (var (indice, pedido) in pedidos.Index())\n{\n    Console.WriteLine($\"Pedido #{indice}: {pedido.Cliente} - ${pedido.Monto}\");\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Nuevos miembros partial (C# 13)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code\">\/\/ C# 13: propiedades y constructores pueden ser partial\n\/\/ Muy \u00fatil con source generators (EF Core, Roslyn generators)\n\npublic partial class Entidad\n{\n    \/\/ Declaraci\u00f3n en el archivo principal\n    public partial string Nombre { get; set; }\n    public partial void OnNombreCambiado();\n}\n\npublic partial class Entidad\n{\n    \/\/ Implementaci\u00f3n en el archivo generado (o viceversa)\n    public partial string Nombre\n    {\n        get =&gt; field;\n        set { field = value; OnNombreCambiado(); }\n    }\n    \n    public partial void OnNombreCambiado() \n        =&gt; Console.WriteLine($\"Nombre cambi\u00f3 a: {Nombre}\");\n}<\/code><\/pre>\n\n<hr class=\"wp-block-separator\"\/>\n<p><em><a href=\"https:\/\/maurobernal.com.ar\/blog\/?p=1256\">\u2190 C# 12: Primary Constructors, Collection Expressions y el c\u00f3digo que deber\u00eda haber existido siempre<\/a> | <strong>Serie .NET 8 \u2192 .NET 10<\/strong> | Pr\u00f3ximo: <a href=\"https:\/\/maurobernal.com.ar\/blog\/?p=1258\">La palabra clave field en C# 14: adi\u00f3s para siempre a los backing fields repetitivos \u2192<\/a><\/em><\/p>","protected":false},"excerpt":{"rendered":"<p>C# 13 con .NET 9: params ReadOnlySpan elimina allocations, System.Threading.Lock hace el threading m\u00e1s seguro, Task.WhenEach simplifica el procesamiento as\u00edncrono y LINQ gana CountBy\/AggregateBy.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[202],"tags":[300,211,18,295,187,65,311,301],"class_list":["post-1257","post","type-post","status-publish","format-standard","hentry","category-dotnet","tag-async","tag-csharp","tag-dotnet","tag-dotnet9","tag-linq","tag-performance","tag-span","tag-threading"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>C# 13: params modernos, Lock de primera clase y Task.WhenEach &#183; devops Mauro Bernal<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"C# 13: params modernos, Lock de primera clase y Task.WhenEach &#183; devops Mauro Bernal\" \/>\n<meta property=\"og:description\" content=\"C# 13 con .NET 9: params ReadOnlySpan elimina allocations, System.Threading.Lock hace el threading m\u00e1s seguro, Task.WhenEach simplifica el procesamiento as\u00edncrono y LINQ gana CountBy\/AggregateBy.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/\" \/>\n<meta property=\"og:site_name\" content=\"devops Mauro Bernal\" \/>\n<meta property=\"article:published_time\" content=\"2026-03-12T11:57:45+00:00\" \/>\n<meta name=\"author\" content=\"Mauro Bernal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@_maurobernal\" \/>\n<meta name=\"twitter:site\" content=\"@_maurobernal\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mauro Bernal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minuto\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/\"},\"author\":{\"name\":\"Mauro Bernal\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"headline\":\"C# 13: params modernos, Lock de primera clase y Task.WhenEach\",\"datePublished\":\"2026-03-12T11:57:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/\"},\"wordCount\":299,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"keywords\":[\"async\",\"csharp\",\"dotnet\",\"dotnet9\",\"Linq\",\"performance\",\"span\",\"threading\"],\"articleSection\":[\"DotNet\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/\",\"url\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/\",\"name\":\"C# 13: params modernos, Lock de primera clase y Task.WhenEach &#183; devops Mauro Bernal\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#website\"},\"datePublished\":\"2026-03-12T11:57:45+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/csharp-13-params-span-lock-task-wheneach-dotnet9\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"C# 13: params modernos, Lock de primera clase y Task.WhenEach\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/\",\"name\":\"devops Mauro Bernal\",\"description\":\"Cuando tu trabajo es hacer que las cosas funcionen bien...\",\"publisher\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\",\"name\":\"Mauro Bernal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"width\":1740,\"height\":1740,\"caption\":\"Mauro Bernal\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\"},\"description\":\"Desarrollo de Sistemas en .Net, IT Callcenters, DBA de SQL Server, Mikrotik, Pentest y T\u00e9cnico consultor de Sistemas Bejerman\",\"sameAs\":[\"https:\\\/\\\/maurobernal.com.ar\",\"https:\\\/\\\/x.com\\\/_maurobernal\",\"https:\\\/\\\/youtube.com\\\/maurobernal\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"C# 13: params modernos, Lock de primera clase y Task.WhenEach &#183; devops Mauro Bernal","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/","og_locale":"es_ES","og_type":"article","og_title":"C# 13: params modernos, Lock de primera clase y Task.WhenEach &#183; devops Mauro Bernal","og_description":"C# 13 con .NET 9: params ReadOnlySpan elimina allocations, System.Threading.Lock hace el threading m\u00e1s seguro, Task.WhenEach simplifica el procesamiento as\u00edncrono y LINQ gana CountBy\/AggregateBy.","og_url":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/","og_site_name":"devops Mauro Bernal","article_published_time":"2026-03-12T11:57:45+00:00","author":"Mauro Bernal","twitter_card":"summary_large_image","twitter_creator":"@_maurobernal","twitter_site":"@_maurobernal","twitter_misc":{"Escrito por":"Mauro Bernal","Tiempo de lectura":"1 minuto"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/#article","isPartOf":{"@id":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/"},"author":{"name":"Mauro Bernal","@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"headline":"C# 13: params modernos, Lock de primera clase y Task.WhenEach","datePublished":"2026-03-12T11:57:45+00:00","mainEntityOfPage":{"@id":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/"},"wordCount":299,"commentCount":0,"publisher":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"keywords":["async","csharp","dotnet","dotnet9","Linq","performance","span","threading"],"articleSection":["DotNet"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/","url":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/","name":"C# 13: params modernos, Lock de primera clase y Task.WhenEach &#183; devops Mauro Bernal","isPartOf":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#website"},"datePublished":"2026-03-12T11:57:45+00:00","breadcrumb":{"@id":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/maurobernal.com.ar\/blog\/csharp-13-params-span-lock-task-wheneach-dotnet9\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/maurobernal.com.ar\/blog\/"},{"@type":"ListItem","position":2,"name":"C# 13: params modernos, Lock de primera clase y Task.WhenEach"}]},{"@type":"WebSite","@id":"https:\/\/maurobernal.com.ar\/blog\/#website","url":"https:\/\/maurobernal.com.ar\/blog\/","name":"devops Mauro Bernal","description":"Cuando tu trabajo es hacer que las cosas funcionen bien...","publisher":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/maurobernal.com.ar\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":["Person","Organization"],"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283","name":"Mauro Bernal","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","url":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","contentUrl":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","width":1740,"height":1740,"caption":"Mauro Bernal"},"logo":{"@id":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1"},"description":"Desarrollo de Sistemas en .Net, IT Callcenters, DBA de SQL Server, Mikrotik, Pentest y T\u00e9cnico consultor de Sistemas Bejerman","sameAs":["https:\/\/maurobernal.com.ar","https:\/\/x.com\/_maurobernal","https:\/\/youtube.com\/maurobernal"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/comments?post=1257"}],"version-history":[{"count":1,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1257\/revisions"}],"predecessor-version":[{"id":1266,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1257\/revisions\/1266"}],"wp:attachment":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/media?parent=1257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/categories?post=1257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/tags?post=1257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}