¿Hay alguna forma de formatear una cadena por nombre en lugar de posición en C #?
En python, puedo hacer algo como este ejemplo (descaradamente robado de aquí ):
>>> print '%(language)s has %(#)03d quote types.' % \
{'language': "Python", "#": 2}
Python has 002 quote types.
¿Hay alguna forma de hacer esto en C #? Digamos por ejemplo:
String.Format("{some_variable}: {some_other_variable}", ...);
Sería capaz de hacer esto usando un nombre de variable sería bueno, pero un diccionario también es aceptable.
c#
.net-3.5
string-formatting
Jason Baker
fuente
fuente
Respuestas:
No hay un método incorporado para manejar esto.
Aquí hay un método
Aquí está otro
Un tercer método mejorado parcialmente basado en los dos anteriores , de Phil Haack
fuente
Tengo una implementación que acabo de publicar en mi blog aquí: http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx
Aborda algunos problemas que tienen estas otras implementaciones con el escape de llaves. La publicación tiene detalles. También hace lo DataBinder.Eval, pero sigue siendo muy rápido.
fuente
Se agregaron cadenas interpoladas en C # 6.0 y Visual Basic 14
Ambos se presentaron a través del nuevo compilador de Roslyn en Visual Studio 2015 .
C # 6.0:
return "\{someVariable} and also \{someOtherVariable}"
Oreturn $"{someVariable} and also {someOtherVariable}"
fuente: novedades en C # 6.0
VB 14:
return $"{someVariable} and also {someOtherVariable}"
Características notables (en Visual Studio 2015 IDE):
{index}
funciona, sino que también{(index + 1).ToString().Trim()}
¡Disfrutar! (y haz clic en "Enviar una sonrisa" en el VS)
fuente
También puede usar tipos anónimos como este:
Por supuesto, requeriría más código si también desea analizar el formato, pero puede formatear una cadena usando esta función como:
fuente
No parece haber una manera de hacer esto fuera de la caja. Sin embargo, parece factible implementar uno propio
IFormatProvider
que se vincule aIDictionary
valores for.Salidas:
La advertencia es que no se puede mezclar
FormatProviders
, por lo que el formato de texto elegante no se puede usar al mismo tiempo.fuente
El marco en sí no proporciona una manera de hacer esto, pero puedes echar un vistazo a esta publicación de Scott Hanselman. Ejemplo de uso:
Este código de James Newton-King es similar y funciona con subpropiedades e índices,
El código de James se basa en System.Web.UI.DataBinder para analizar la cadena y requiere hacer referencia a System.Web, que a algunas personas no les gusta hacer en aplicaciones que no son web.
EDITAR: Ah, y funcionan muy bien con tipos anónimos, si no tiene un objeto con propiedades listas para ello:
fuente
Ver /programming/271398?page=2#358259
Con la extensión vinculada a puede escribir esto:
y obtendrás
"foo 2 System.Object
".fuente
Creo que lo más cercano que obtendrás es un formato indexado:
También hay String.Replace (), si está dispuesto a hacerlo en varios pasos y tiene fe en que no encontrará sus 'variables' en ningún otro lugar de la cadena:
Expandiendo esto para usar una Lista:
También puede hacer eso con un Dictionary <string, string> iterando sus colecciones .Keys, pero usando List <KeyValuePair <string, string >> podemos aprovechar el método .ForEach () de List y condensarlo nuevamente en una línea:
Una lambda sería aún más simple, pero todavía estoy en .Net 2.0. También tenga en cuenta que el rendimiento .Replace () no es estelar cuando se usa de forma iterativa, ya que las cadenas en .Net son inmutables. Además, esto requiere que la
MyString
variable se defina de tal manera que sea accesible para el delegado, por lo que aún no es perfecta.fuente
Mi biblioteca de código abierto, Regextra , admite el formato con nombre (entre otras cosas). Actualmente apunta a .NET 4.0+ y está disponible en NuGet . También tengo una entrada de blog introductoria al respecto: Regextra: que te ayuda a reducir tus (problemas) {2} .
El bit de formato con nombre admite:
Ejemplo:
Resultado:
Consulte el enlace de GitHub del proyecto (arriba) y la wiki para ver otros ejemplos.
fuente
Revisa este:
Muestra:
El rendimiento es bastante bueno en comparación con otras soluciones.
fuente
Dudo que esto sea posible. Lo primero que viene a la mente es cómo vas a acceder a los nombres de las variables locales.
Sin embargo, puede haber alguna forma inteligente de usar expresiones LINQ y Lambda para hacer esto.
fuente
Aquí hay uno que hice hace un tiempo. Extiende String con un método Format tomando un solo argumento. Lo bueno es que usará la cadena estándar. Formatee si proporciona un argumento simple como un int, pero si usa algo como tipo anónimo, también funcionará.
Ejemplo de uso:
Resultaría en "La familia Smith tiene 4 hijos".
No hace cosas locas vinculantes como matrices e indexadores. Pero es súper simple y de alto rendimiento.
fuente
Ejemplo:
Salida: 你好, wayjet, 今天 是 2011-05-04, 这 是 你 第 18 次 登录 , 积分 {100.40}
fuente
Aquí hay un método simple para cualquier objeto:
Y aquí cómo usarlo:
salida: 27/02/2012
fuente
Implementé esta es una clase simple que duplica la funcionalidad de String.Format (excepto cuando se usan clases). Puede usar un diccionario o un tipo para definir campos.
https://github.com/SergueiFedorov/NamedFormatString
C # 6.0 está agregando esta funcionalidad directamente a la especificación del lenguaje, por lo que
NamedFormatString
es para compatibilidad con versiones anteriores.fuente
Resolví esto de una manera ligeramente diferente a las soluciones existentes. Realiza el núcleo del reemplazo del elemento nombrado (no el bit de reflexión que algunos han hecho). Es extremadamente rápido y simple ... Esta es mi solución:
Se usa de la siguiente manera:
¡Espero que alguien encuentre esto útil!
fuente
A pesar de que la respuesta aceptada da algunos buenos ejemplos, el .Inject y algunos de los ejemplos de Haack no manejan el escape. Muchos también dependen en gran medida de Regex (más lento) o DataBinder.Eval, que no está disponible en .NET Core, y en algunos otros entornos.
Con eso en mente, he escrito un analizador basado en una máquina de estado simple que fluye a través de caracteres, escribiendo en una
StringBuilder
salida, carácter por carácter. Se implementa comoString
método (s) de extensión y puede tomar tantoDictionary<string, object>
aoobject
con parámetros como entrada (usando la reflexión).Maneja niveles ilimitados
{{{escaping}}}
y tiraFormatException
cuando la entrada contiene llaves desequilibradas y / u otros errores.En última instancia, toda la lógica se reduce a 10 estados principales: porque cuando la máquina de estado está fuera de un paréntesis y del mismo modo dentro de un paréntesis, el siguiente carácter es una llave abierta, una llave abierta con escape, una llave cerrada con escape, una llave cerrada con escape, o un personaje ordinario. Cada una de estas condiciones se maneja individualmente a medida que avanza el ciclo, agregando caracteres a una salida
StringBuffer
o una claveStringBuffer
. Cuando se cierra un parámetro, el valor de la claveStringBuffer
se utiliza para buscar el valor del parámetro en el diccionario, que luego se introduce en la salidaStringBuffer
. Al final,StringBuffer
se devuelve el valor de la salida .fuente
Editar: Lo que debería haber dicho fue: "No, no creo que lo que quieres hacer esté respaldado por C #. Esto es lo más cercano que vas a tener".
fuente
"someString" + someVariable + "someOtherString"
más legible. Este artículo está de acuerdo contigo.