No se puede usar String.Vacío como valor predeterminado para un parámetro opcional
Estoy leyendo C#efectivo por Bill Wagner. En Item 14-Minimize Duplicate Initialization Logic , muestra el siguiente ejemplo de uso de la nueva característica de parámetros opcionales en un constructor:
public MyClass(int initialCount = 0, string name = "")
Observe que usó ""
en lugar de string.Empty
.
Él comenta:
Notará [en un ejemplo anterior] que el segundo constructor especificó "" para el valor predeterminado en el parámetro name, en lugar del parámetro más habitual
string.Empty
. Esto se debe a questring.Empty
no es una constante en tiempo de compilación. Es una propiedad estática definida en la clase string. Debido a que no es una constante de compilación, no puede usarla para el valor predeterminado de un parámetro.
Si no podemos usar la string.Empty
estática en todas las situaciones, entonces ¿eso no derrota el propósito de la misma? Pensé que lo usaríamos para asegurarnos de que tenemos un medio independiente del sistema para referirnos a la cadena vacía. ¿Está mal mi entendimiento? Gracias.
ACTUALIZAR
Solo un comentario de seguimiento. Según MSDN:
Cada parámetro opcional tiene un valor predeterminado como parte de su definición. Si no se envía ningún argumento para ese parámetro, se utiliza el valor predeterminado. Los valores predeterminados deben ser constantes.
Entonces tampoco podemos usar System.Environment.NewLine
, o usar objetos recién instanciados como valores predeterminados. No he usado VS2010 todavía, y esto es decepcionante!
9 answers
A partir del compilador de C# 2.0, hay muy poco sentido para String.Empty
de todos modos, y de hecho en muchos casos es una pesimización, ya que el compilador puede insertar algunas referencias a ""
pero no puede hacer lo mismo con String.Empty
.
En C# 1.1 era útil evitar crear muchos objetos independientes que contuvieran la cadena vacía, pero esos días se han ido. ""
funciona muy bien.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-23 19:16:55
No hay nada que le impida definir su propia constante para la cadena vacía si realmente desea usarla como un valor de parámetro opcional:
const string String_Empty = "";
public static void PrintString(string s = String_Empty)
{
Console.WriteLine(s);
}
[Como un aparte, una razón para preferir String.Empty
sobre ""
en general, que no se ha mencionado en las otras respuestas, es que hay varios caracteres Unicode (ensambladores de ancho cero, etc.) que son efectivamente invisibles a simple vista. Así que algo que se parece a ""
no es necesariamente la cadena vacía, mientras que con String.Empty
sepa exactamente lo que está usando. Reconozco que esta no es una fuente común de errores, pero es posible.]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-25 11:12:46
De la pregunta original:
Pensé que lo usaríamos para asegurarnos de que tenemos un medio independiente del sistema para referirnos a la cadena vacía.
¿De qué manera puede variar la cadena vacía de un sistema a otro? ¡Siempre es una cadena sin caracteres! Estaría realmente asustado si alguna vez encontrara una implementación donde string.Empty == ""
devolviera false :) Esto es no lo mismo que algo como Environment.NewLine
.
De Counter Terrorist's bounty mensaje:
Quiero Cadena.Empty se puede usar como parámetro predeterminado en la próxima versión de C#. : D
Bueno, eso ciertamente no va a suceder.
Aunque personalmente me hubiera gustado un mecanismo predeterminado muy diferente también, la forma en que funcionan los parámetros opcionales ha estado en. NET desde el principio , y siempre significa incrustar una constante en los metadatos, de modo que el código de llamada pueda copiar esa constante en el sitio de la llamada si no hay un argumento correspondiente proporcionar.
Con string.Empty
es realmente inútil - usar ""
hará lo que quieras; ¿es que doloroso usar el literal de cadena? (Yo uso el literal en todas partes - nunca uso string.Empty
- pero ese es un argumento diferente.)
Eso es lo que me sorprende de esta pregunta - la queja gira en torno a algo que no realmente causa un problema real. Es más importante en los casos en los que desea que el valor predeterminado se calcule en el momento de la ejecución porque podría variar. Por ejemplo, podría imaginar casos en los que desea poder llamar a un método con un parámetro DateTime
y tenerlo por defecto en "la hora actual". Por el momento, la única solución vagamente elegante que conozco es:
public void RecordTime(string message, DateTime? dateTime = null)
{
var realDateTime = dateTime ?? DateTime.UtcNow;
}
... pero eso no siempre es apropiado.
En conclusión:
- Dudo mucho que esto alguna vez sea parte de C#{[46]]}
- Para
string.Empty
es inútil de todos modos - Para otros valores que realmente no siempre tenga el mismo valor, realmente puede ser un dolor
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-03 08:55:07
Nunca uso string.Vacío, no le veo el sentido. Tal vez lo hace más fácil para las personas que son realmente nuevas en la programación, pero dudo que sea útil incluso para eso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-23 19:13:57
Creo que la idea detrás de string.Vacío es mejora la legibilidad. No es como newline donde hay alguna diferencia entre cómo se representa en diferentes plataformas. Es vergonzoso que no se pueda usar en un parámetro predeterminado. Sin embargo, no causará ningún problema si realiza un puerto entre Windows y algo como Mono en Linux.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-23 19:15:49
Para su información, parece que se impone la misma restricción a los valores pasados a los constructores de atributos: deben ser constantes. Desde string.vacío se define como :
public static readonly string Empty
En lugar de una constante real, no se puede usar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-27 15:23:47
Si realmente no te gustan los literales de cadena, puedes usar:
public static string MyFunction(string myParam= default(string))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-05 14:23:05
Utilizo string.Empty
puramente para la legibilidad.
Si alguien más necesita leer/cambiar mi código más tarde, saben que quería verificar o establecer algo en una cadena vacía. Usar solo ""
a veces puede causar errores y confusión porque puede que haya olvidado poner la cadena que quería allí.
Por ejemplo:
if(someString == string.Empty)
{
}
Vs
if(someString == "")
{
}
La primera if
declaración me parece mucho más deliberada y legible. Porque esto es sólo una preferencia sin embargo, realmente no veo el tren-smash en tener que usar ""
en lugar de string.Empty
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-22 10:52:44
Tal vez la mejor solución a este problema es una sobrecarga de este método, de esta manera:
public static void PrintString()
{
PrintString(string.Empty);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-26 07:15:58