2009-09-15 10 views
6

es realmente molesto cómo C# parece obligarle a nombrar explícitamente el índice de cada parámetro en String.Format, si desea agregar otro parámetro en algún lugar, o bien tiene que volver a indexar la cadena o poner tu nuevo parámetro al final.String.Format parámetro orden molestar

¿Hay alguna manera de hacer que C# haga esto automáticamente?

p. Ej. (Sé que esto es pedantes sin sentido, es sólo un ejemplo :)

comienzo con:

String.Format("{0} {1} {1} {2} {3}", a, b, c, d) 

si quiero agregar un parámetro al principio me puede hacer una de las siguientes:

String.Format("{4} {0} {1} {1} {2} {3}", a, b, c, d, e) 
String.Format("{0} {1} {2} {2} {3} {4}", e, a, b, c, d) 

en Delphi, por ejemplo, lo que podía hacer el equivalente a esto:

String.Format("{} {} {} {2} {} {}", e, a, b, c, d) 
+0

¿Ambas líneas en C# y delphi devuelven lo mismo? – Beatles1692

Respuesta

23

Bueno, no hay nada en C# para hacer º es automáticamente para ti. Siempre puedes escribir tu propio método para hacerlo, pero francamente me parece menos legible. Hay mucho más que pensar que hacer (IMO) para entender lo que hace su línea final que la anterior. Al llegar a la {2} usted tiene que dar marcha atrás y vuelva a colocar el elemento anterior con {3} para saltar el {2} etc.

personalmente prefiero código que tarda un poco más que escribir mentalmente, pero está claro para leer.

+7

+1: la capacidad de mantenimiento siempre debería ganar más de un ahorro cuando se escribía originalmente. – Richard

+5

+1 "Los programas de ordenador deben ser diseñados para los seres humanos de leer y por cierto están a cargo de los ordenadores" ¿Qué hay de –

+0

String.Format ("{a} {B} {B} {C} {d}", a, b, c , d)? ¿Podría esto agregarse en .NET 4.0? Quizás el compilador podría ayudar. O nuevo DLR? Probablemente me falta algo aquí, pero sería bueno ... –

2

La función que solicita no forma parte del marco. Aquí hay un buen método de extensión que he encontrado que proporciona parámetros con nombre C#. Creo que Marc Gravell lo publicó o uno de esos otros gurús SO.

 static readonly Regex rePattern = new Regex(@"\{([^\}]+)\}", RegexOptions.Compiled); 


    /// <summary> 
    /// Shortcut for string.Format. Format string uses named parameters like {name}. 
    /// 
    /// Example: 
    /// string s = Format("{age} years old, last name is {name} ", new {age = 18, name = "Foo"}); 
    /// 
    /// </summary> 
    /// <param name="format"></param> 
    /// <param name="values"></param> 
    /// <returns></returns> 
    public static string FN<T>(this string pattern, T template) 
    { 
     Dictionary<string, string> cache = new Dictionary<string, string>(); 
     return rePattern.Replace(pattern, match => 
     { 
      string key = match.Groups[1].Value; 
      string value; 

      if (!cache.TryGetValue(key, out value)) 
      { 
       var prop = typeof(T).GetProperty(key); 
       if (prop == null) 
       { 
        throw new ArgumentException("Not found: " + key, "pattern"); 
       } 
       value = Convert.ToString(prop.GetValue(template, null)); 
       cache.Add(key, value); 
      } 
      return value; 
     }); 
    } 
+0

¡Agradable, pero tiene un gran impacto en el rendimiento! – ShloEmi

1

Aunque C# no puede hacer esto por usted, la herramienta podría ayudar aquí.

Resharper, por ejemplo, le advierte si tiene más parámetros en la cadena que después de la cadena. Miré si se admite la reordenación de parámetros en Resharper, pero en este caso no es así (R # admite la modificación de la firma del método, pero eso no ayuda aquí).

Mire Code Rush from DevEx. Es muy probable que esa herramienta tenga lo que necesita.

1

Sé que esto es viejo, estoy de acuerdo con Jon. Incluso con una cadena de gran formato (vea el siguiente ejemplo de código), todavía me toma menos de 1 minuto rehacer las ubicaciones de índice de los elementos si tengo que agregar algo, y creo que es más fácil de mantener y legible y luego intento crear un método para automatizar el proceso. El problema con la automatización es cuando trato de ver el código unas semanas más tarde ... no se puede entender a primera vista. Además, una vez que aprendes bien Visual Studio y aprendes a usar cosas como el modo de edición en bloque y algunas de las otras funciones avanzadas, puedes ser bastante productivo.

//----------------------------------------------------------------------------- 
// <copyright file="ShellForm.cs" company="DCOM Productions"> 
//  Copyright (c) DCOM Productions. All rights reserved. 
// </copyright> 
//----------------------------------------------------------------------------- 

string updateCommandText = string.Format("UPDATE `moh`.`moh` SET ageact = '{0}', branch = '{1}', cemetary = '{2}', citation = '{3}', citycement = '{4}', cdateact = '{5}', cdateaward = '{6}', cdatebirth = '{7}', cdatedeath = '{8}', namefirst = '{9}', namelast = '{10}', placeact = '{11}', placeenter = '{12}', presat = '{13}', presby = '{14}', rankact = '{15}', rankawd = '{16}', rankhigh = '{17}', synopsis = '{18}', unit = '{19}', war = '{20}', imgfile = '{21}' WHERE ID = '{22}'", 
    /* {0} */ uxAgeAct.Text.Replace("'", "''"), 
    /* {1} */ uxBranch.Text.Replace("'", "''"), 
    /* {2} */ uxCemetary.Text.Replace("'", "''"), 
    /* {3} */ uxCitation.Text.Replace("'", "''"), 
    /* {4} */ uxCityCemetary.Text.Replace("'", "''"), 
    /* {5} */ uxDateAct.Text.Replace("'", "''"), 
    /* {6} */ uxDateAward.Text.Replace("'", "''"), 
    /* {7} */ uxDateBirth.Text.Replace("'", "''"), 
    /* {8} */ uxDateDiceased.Text.Replace("'", "''"), 
    /* {9} */ uxNameFirst.Text.Replace("'", "''"), 
    /* {10} */ uxNameLast.Text.Replace("'", "''"), 
    /* {11} */ uxPlaceAct.Text.Replace("'", "''"), 
    /* {12} */ uxPlaceEnter.Text.Replace("'", "''"), 
    /* {13} */ uxPresentedAt.Text.Replace("'", "''"), 
    /* {14} */ uxPresentedBy.Text.Replace("'", "''"), 
    /* {15} */ uxRankAct.Text.Replace("'", "''"), 
    /* {16} */ uxRankAwarded.Text.Replace("'", "''"), 
    /* {17} */ uxRankHigh.Text.Replace("'", "''"), 
    /* {18} */ uxSynopsis.Text.Replace("'", "''"), 
    /* {19} */ uxUnit.Text.Replace("'", "''"), 
    /* {20} */ uxWar.Text.Replace("'", "''"), 
    /* {21} */ uxImgFile.Text.Replace("'", "''"), 
    /* {22} */ dataRow["ID"].ToString()); 
3

A partir de Visual Studio 2015 se puede paso lateral este problema utilizando Interpolated Strings (es un truco compilador, por lo que no importa qué versión de .NET Framework a apuntar).

continuación, el código se ve algo como esto

string txt = $"{person.ForeName} is not at home {person.Something}"; 

Creo que hace propenso el código más legible y menos errores.