parameter - C#4.0-Cómo manejar los parámetros de cadena opcionales
optional parameter c# (6)
Estoy respondiendo esta pregunta.
Why can they not make String.Empty a compile-time constant?
Aquí está el código de desarme a través del Reflector de String.cs en mscorlib.dll
public static readonly Empty;
static String()
{
Empty = "";
WhitespaceChars = new char[] {
''/t'', ''/n'', ''/v'', ''/f'', ''/r'', '' '', ''/x0085'', ''/x00a0'', '' '', '' '', '' '', '' '', '' '', '' '', '' '', '' '',
'' '', '' '', '' '', '' '', '''', ''/u2028'', ''/u2029'', '' '', ''''
};
}
Así que en la plataforma de Windows, string.Empty es exactamente "". Pero, sabes, Martian tiene una definición diferente para Empty y WhitespaceChars en su sistema operativo.
Este código no es válido:
private void Foo(string optionalString = string.Empty)
{
// do foo.
}
Pero este código es:
private void Foo(string optionalString = "")
{
// do foo.
}
¿Por qué? Debido a que string.Empty es un campo de solo lectura, no una constante, y los valores predeterminados para los parámetros opcionales deben ser una constante de compilación.
Entonces, en mi pregunta ... (bueno, preocupación)
Esto es lo que he tenido que hacer:
private const string emptyString = "";
private void Foo(string optionalString = emptyString)
{
// do foo.
if (!string.IsNullOrEmpty(optionalString))
// etc
}
¿Cómo manejan los parámetros de cadena opcionales?
¿Por qué no pueden hacer que String.Empty una constante de compilación?
La mejor manera de manejarlos es con:
private void Foo(string optionalString = "")
{
// do foo.
}
Así que no puedes usar String.Empty. Todos reconocen "", pero si encontrara la optionalString = nullString
no estaría seguro de qué pensar. Si nada más, nombre la cosa emptyString
- ¡no es nulo!
Si está dispuesto a jugar a perder y tratar nulos, "", y que los caracteres de espacio en blanco sean los mismos, entonces puede predeterminar a null
. Esto resulta muy útil cuando el nombre de usuario y la contraseña son campos opcionales debido a la posibilidad de una conexión confiable a un db. Podría cambiar esta lógica para restablecer las cadenas a null
y, por lo tanto, modificar el aserto y el if
. La parte importante es tener una convención consistente.
private void RunSql(string serverName, string databaseName, string userName = null, string password = null)
{
userName = Strip(userName);
password = Strip(password);
// The `MsTest` assert - works in both `Debug` and `Release` modes.
Assert.AreEqual<bool>(
userName == String.Empty,
password == String.Empty,
"User name and password should be either both empty or both non-empty!");
Assert.IsFalse(String.IsNullOrWhiteSpace(serverName));
Assert.IsFalse(String.IsNullOrWhiteSpace(databaseName));
var cmdBuilder = new StringBuilder();
cmdBuilder.AppendFormat("sqlcmd -E -S {0} -d {1} ", serverName, databaseName);
if (userName.Length > 0)
{
cmdBuilder.AppendFormat("-U {0} -P {1} ", userName, password);
}
// Complete the command string.
// Run the executable.
}
// Cannot think of a good name. Emptify? MakeNullIfEmpty?
private string Strip(string source)
{
if (String.IsNullOrWhiteSpace(source))
{
return String.Empty;
}
return source;
}
Ummm ... ¿qué pasa con la cadena opcionalParm = "" de nuevo? ¿Por qué es tan malo? ¿Realmente crees que necesitas una constante simbólica para una cadena vacía en este caso? ¿Qué tal esto entonces?
const int Zero = 0;
void SomeMethod(int optional = Zero) { }
¿Eso te parece una tontería?
si no te gusta el valor "", puedes usar el valor predeterminado (cadena).
Jugué con él y está permitido.
private static void foo(string param = default(string)) {
if (!string.IsNullOrEmpty(param)) // or param != default(string)
Console.WriteLine(param);
}
La advertencia de análisis de código 1026 dice que no se deben usar parámetros opcionales. Es mejor estilo usar métodos de sobrecarga, como este:
private void Foo()
{
Foo(string.Empty);
}
private void Foo(string optionalString)
{
// do foo.
if (!string.IsNullOrEmpty(optionalString))
// etc
}