Perché non esiste Char.Empty come String.Empty?


259

C'è una ragione per questo? Ti chiedo perché se hai bisogno di usare molti caratteri vuoti, ti trovi nella stessa situazione che avresti quando usi un sacco di stringhe vuote.

Modifica: il motivo di questo utilizzo è stato questo:

myString.Replace ('c', '')

Quindi rimuovere tutte le istanze di 'c's da myString.


1
Sì, ho usato quella parola per mancanza di una parola migliore. cioè il modo raccomandato di usare String.Empty invece di "".
Joan Venge,

3
Se a volte ti preoccupi di errori di digitazione '', perché non semplicemente avvolgere la funzionalità in un metodo di estensione lungo le linee di RemoveAll(this string s, params char[] toRemove)? L'intenzione sarà chiaramente comunicata e non rischierai di sbagliare a scrivere nulla.
bzlm,

12
@Henk - L'unico motivo per cui utilizzo string.Empty è perché trovo che l'oggetto null fornito da Empty esprime un intento migliore delle virgolette vuote. Le virgolette vuote potrebbero derivare da un problema di unione, o da un pensiero confuso, oppure potrebbe essere l'intento reale di quel codice, mentre Vuoto mi dice esplicitamente che lo sviluppatore intendeva che quella stringa non avesse dati.
Ritch Melton,

3
C'è una differenza tra "" e string.Empty. A nessuno importa, davvero, ma "" crea un oggetto, mentre string.Empty ne fa uso uno già fatto. Ma ancora una volta, è così piccolo, che solo le situazioni speciali farebbero una differenza
marcelo-ferraz,

1
@ marcelo-ferrazm, about ""crea un oggetto : No, non lo fa.
Henk Holterman,

Risposte:


272

Non esiste un carattere vuoto. Il più vicino che puoi ottenere è '\0'il carattere "null" Unicode. Dato che puoi incorporarlo all'interno di letterali stringa o esprimerlo da solo molto facilmente, perché dovresti desiderare un campo separato per esso? Allo stesso modo, gli argomenti "è facile da confondere ""e " "" non si applicano '\0'.

Se potessi dare un esempio di dove vorresti usarlo e perché pensi che sarebbe meglio, ciò potrebbe aiutare ...


2
\ 0 non è il carattere 'end of the array array'? O sto confondendo con qualcos'altro?
Bertvan,

5
@Bertvan: Perché dovrebbe esserci un carattere alla fine di un array di byte ? È usato per stringhe "null terminated", sì.
Jon Skeet,

35
Char.MinValue è meglio di '\ 0'
Aliostad

10
@Aliostad: Per interesse, se ci fosse un campo simile per Int32.Zero, lo useresti al posto dello 0 letterale? In caso contrario, qual è la differenza qui?
Jon Skeet,

7
@Adam, @Jon - qual è il codice per Bell? O backspace meglio, pensa pensa ... O forse invece di pensare che sia semplicemente meglio scrivere Char.Backspace? Un altro motivo - dici che è meglio scrivere '0' per terminator, invece, dì Char.Terminator, comunque non lo è - è troppo facile fare un refuso (completamente compilato, vedi sopra), ma prova a scrivere Char.Termnator. Ci sono motivi sufficienti per evitare valori grezzi non verificabili (missioni spaziali fallite a causa di stupidi errori di battitura del genere).
Greenoldman,

87

Un carattere, a differenza di una stringa, è una cosa discreta con una dimensione fissa. Una stringa è davvero un contenitore di caratteri.

Quindi, Char.Empty non ha davvero senso in quel contesto. Se hai un carattere, non è vuoto.


3
Completamente giusto. Ha senso chiedere se un contenitore è vuoto o meno. Non ha senso chiedere di un int o float o char è vuoto.
TED

1
@Joe: Allora come può essere vuota una stringa se una stringa è una raccolta di caratteri (non vuoti)? Probabilmente stupido, scusa ...
user1477388

9
Poiché una stringa non è i singoli oggetti, è la raccolta. Pensa a un secchio di rocce. Non posso avere una roccia vuota. Ma posso avere un secchio vuoto.
Joe

2
Lo definirei come "un carattere è un tipo di valore primitivo e una stringa non è un tipo di riferimento".
samis,

3
Questa è la vera risposta.
Gandalf458,

31

Non esiste un personaggio vuoto. Contiene sempre qualcosa . Anche '\ 0' è un personaggio.


28

Usa Char.MinValuequale funziona allo stesso modo di '\ 0'. Ma fai attenzione, non è lo stesso di String.Empty.


Grazie, non l'ho mai visto prima. Sai se funziona in myString.Replace ('c', Char.MinValue)? Dovrei provarlo.
Joan Venge,

19

È possibile utilizzare caratteri nullable .

char? c

Questo permette ''? O semplicemente null?
Joan Venge,

Nel tuo caso, potresti farlo: myString.Replace ("c", (c == null? "": C.ToString ()))
paquetp

12

Se non hai bisogno dell'intera stringa, puoi sfruttare l'esecuzione ritardata:

public static class StringExtensions
{
    public static IEnumerable<char> RemoveChar(this IEnumerable<char> originalString, char removingChar)
    {
        return originalString.Where(@char => @char != removingChar);
    }
}

Puoi anche combinare più personaggi ...

string veryLongText = "abcdefghijk...";

IEnumerable<char> firstFiveCharsWithoutCsAndDs = veryLongText
            .RemoveChar('c')
            .RemoveChar('d')
            .Take(5);

... e saranno valutati solo i primi 7 caratteri :)

EDIT: o, ancora meglio:

public static class StringExtensions
{
    public static IEnumerable<char> RemoveChars(this IEnumerable<char> originalString,
        params char[] removingChars)
    {
        return originalString.Except(removingChars);
    }
}

e il suo utilizzo:

        var veryLongText = "abcdefghijk...";
        IEnumerable<char> firstFiveCharsWithoutCsAndDs = veryLongText
            .RemoveChars('c', 'd')
            .Take(5)
            .ToArray(); //to prevent multiple execution of "RemoveChars"

@Joan: grazie ... anche se "Genius" è un po 'esagerato: P (non so delle sue prestazioni quando si rimuovono Chars diventerà un grande array ...)
Notoriousxl

1
Ieri ho dimenticato: presta attenzione a come stai utilizzando la variabile di risultato "firstFiveCharsWithoutCsAndDs". Se non si desidera passarlo a un altro metodo "yield" (come quelli di LINQ), chiamare immediatamente un ".ToArray ()" dopo "Take (5)" ... altrimenti, "RemoveChars + Take" la catena verrà eseguita ogni volta che accedi alla variabile in modo "tradizionale" (ad esempio, ogni volta che chiami un "Count ()" su di essa, o quando la attraversi in una foreach senza "return return")
Notoriousxl

+1 bel pensiero. ma questo non può essere mantenibile o efficiente come l'approccio di base :)
nawfal,

1
@nawfal in termini di efficienza hai ragione, ma penso che myString.Except ("c") sia più dichiarativo di myString.Replace ('c', ''): P (e si ridimensiona abbastanza bene: myString.Except ( "aeiou"))
Notoriousxl

7
myString = myString.Replace('c'.ToString(), "");

OK, questo non è particolarmente elegante per la rimozione di lettere, poiché il metodo .Replace ha un sovraccarico che accetta parametri di stringa. Ma questo funziona per rimuovere ritorni a capo, avanzamenti di riga, schede, ecc. In questo esempio vengono rimossi i caratteri di tabulazione:

myString = myString.Replace('\t'.ToString(), "");

6

lo stesso motivo per cui non esiste un int.Empty. I contenitori possono essere vuoti. I valori scalari non possono essere. Se intendi 0 (che non è vuoto), usa '\0'. Se vuoi dire null, allora usa null:)


2
null non è possibile in quanto char è un ValueType. Dovresti usare char? per poter assegnare null ad esso.
Femaref,

dovresti renderlo nullable. vedi la mia risposta
paquetp,

5

Un carattere è un tipo di valore, quindi il suo valore non può essere nullo. (A meno che non sia avvolto in un contenitore Nullable).

Dal momento che non può essere nullo, in contiene un codice numerico e ogni codice è associato a un carattere.


4

Non una risposta alla tua domanda, ma per indicare un valore predefinito charpuoi usare solo

default(char)

che è lo stesso di quello char.MinValuea sua volta \0. Non si dovrebbe usare se per qualcosa come una stringa vuota però.


1

Non risponde alla tua prima domanda - ma per il problema specifico che hai avuto, puoi semplicemente usare stringhe invece di caratteri, giusto ?:

myString.Replace("c", "")

C'è un motivo per cui non vorresti farlo?


1

Puoi anche ricostruire il carattere stringa per carattere, esclusi i caratteri di cui vuoi sbarazzarti.

Ecco un metodo di estensione per fare questo:

    static public string RemoveAny(this string s, string charsToRemove)
    {
        var result = "";
        foreach (var c in s)
            if (charsToRemove.Contains(c))
                continue;
            else
                result += c;

        return result;
    }

Non è lucido o elegante, ma funziona bene.

Usa così:

string newString = "My_String".RemoveAny("_"); //yields "MyString"

Usa un StringBuilderper result. Perché non avvolgere return s.Replace(charsToRemove,"");?
aloisdg si trasferisce su codidact.com il

1

Se si desidera rimuovere caratteri che soddisfano una condizione specifica, è possibile utilizzare questo:

string s = "SoMEthInG";
s = new string(s.Where(c => char.IsUpper(c)).ToArray());

(Questo lascerà solo i caratteri maiuscoli nella stringa.)

In altre parole, è possibile "utilizzare" la stringa come una IEnumerable<char>, apportare modifiche su di essa e quindi riconvertirla in una stringa come mostrato sopra.

Ancora una volta, questo permette di rimuovere non solo una specifica char a causa della espressione lambda, anche se è possibile farlo se si cambia l'espressione lambda in questo modo: c => c != 't'.


0

Che ne dite di BOM , il carattere magico che Microsoft aggiunge all'inizio dei file (almeno XML)?


La formulazione su Wikipedia qui è piuttosto sfortunata; la DBA non è un personaggio in questo contesto. E qual è la tua domanda esattamente? :)
bzlm,

@onemach, quindi, se si myString.Replace ('c', '')potesse ottenere myString.Replace ('c', UTF_BOM). Quindi direi che la risposta è "che ne dici di ...".
bzlm,

0

se si desidera eliminare il carattere vuoto nella stringa, funzionerà quanto segue, semplicemente convertire in qualsiasi rappresentazione del tipo di dati desiderata. Grazie,

private void button1_Click(object sender, EventArgs e)
    {

        Int32 i;

        String name;

        Int32[] array_number = new int[100];

        name = "1 3  5  17   8    9    6";

        name = name.Replace(' ', 'x');

        char[] chr = name.ToCharArray();


        for (i = 0; i < name.Length; i++)
        {
            if ((chr[i] != 'x'))
            {
                array_number[i] = Convert.ToInt32(chr[i].ToString());
                MessageBox.Show(array_number[i].ToString());
            }

        }

    }

0

In termini di linguaggio C #, ciò che segue potrebbe non avere molto senso. E questa non è una risposta diretta alla domanda. Ma i volatili sono ciò che ho fatto in uno dei miei scenari aziendali

        char? myCharFromUI = Convert.ToChar(" ");
        string myStringForDatabaseInsert = myCharFromUI.ToString().Trim();
        if (String.IsNullOrEmpty(myStringForDatabaseInsert.Trim()))
        {
            Console.Write("Success");
        }

L' nulle white spacedi business diverso avuto scorre nel mio progetto. Durante l'inserimento nel database, devo inserire empty stringnel database se si tratta di uno spazio bianco.


0

So che questo è piuttosto vecchio, ma di recente ho riscontrato un problema con la necessità di effettuare più sostituzioni per rendere sicuro un nome di file. Innanzitutto, nell'ultima stringa .NET. La funzione di sostituzione null è l'equivalente di un carattere vuoto. Detto questo, ciò che manca a .Net è una semplice sostituzione che sostituirà qualsiasi carattere in un array con il carattere desiderato. Non esitate a fare riferimento al codice seguente (funziona in LinqPad per i test).

// LinqPad .ReplaceAll and SafeFileName
void Main()
{

    ("a:B:C").Replace(":", "_").Dump();                     // can only replace 1 character for one character => a_B_C
    ("a:B:C").Replace(":", null).Dump();                    // null replaces with empty => aBC
    ("a:B*C").Replace(":", null).Replace("*",null).Dump();  // Have to chain for multiples 

    // Need a ReplaceAll, so I don't have to chain calls


    ("abc/123.txt").SafeFileName().Dump();
    ("abc/1/2/3.txt").SafeFileName().Dump();
    ("a:bc/1/2/3.txt").SafeFileName().Dump();
    ("a:bc/1/2/3.txt").SafeFileName('_').Dump();
    //("abc/123").SafeFileName(':').Dump(); // Throws exception as expected

}


static class StringExtensions
{

    public static string SafeFileName(this string value, char? replacement = null)
    {
        return value.ReplaceAll(replacement, ':','*','?','"','<','>', '|', '/', '\\');
    }

    public static string ReplaceAll(this string value, char? replacement, params char[] charsToGo){

        if(replacement.HasValue == false){
                return string.Join("", value.AsEnumerable().Where(x => charsToGo.Contains(x) == false));
        }
        else{

            if(charsToGo.Contains(replacement.Value)){
                throw new ArgumentException(string.Format("Replacement '{0}' is invalid.  ", replacement), "replacement");
            }

            return string.Join("", value.AsEnumerable().Select(x => charsToGo.Contains(x) == true ? replacement : x));
        }

    }

}


-3

Il modo più semplice per rimuovere un carattere dalla stringa è di tagliarlo

cl = cl.Trim(' ');

Rimuove tutti gli spazi in una stringa


Questo è utile se si vuole usare use .Replace ('c', '') con il rovescio della medaglia di rimuovere altri spazi bianchi. Ma è più utile di molte altre risposte fornite.
Jan

1
No, questo è sbagliato! Trim rimuove solo i caratteri dall'inizio e dalla fine di una stringa non nel mezzo
userSteve
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.