String.EmptyのようなChar.Emptyがないのはなぜですか?


259

これには理由がありますか?たくさんの空の文字を使用する必要がある場合は、たくさんの空の文字列を使用するのと同じ状況になるので、私は尋ねています。

編集:この使用法の理由はこれでした:

myString.Replace ('c', '')

したがって、myStringから「c」のすべてのインスタンスを削除します。


1
ええ、私はより良い言葉がないためにその言葉を使いました。つまり、 ""の代わりにString.Emptyを使用する推奨方法。
Joan Venge

3
誤ってタイプミスすることが心配な場合は、 '' のように、単に拡張機能の機能を単に次のようにラップするだけではRemoveAll(this string s, params char[] toRemove)どうですか?意図が明確に伝えられ、誤入力のリスクがなくなります。
bzlm

12
@Henk-私がstring.Emptyを使用する唯一の理由は、Emptyによって提供されるnullオブジェクトが、空の引用符よりも意図を表現していることがわかったためです。空の引用符は、マージの問題や混乱した考え、またはそのコードの実際の意図が原因である可能性がありますが、空の引用符は、開発者がその文字列にデータを含めないことを意図していることを明示しています。
リッチメルトン、

3
""とstring.Emptyには違いがあります。実際には誰も気にしませんが、 ""はオブジェクトを作成しますが、string.Emptyはすでに作成されたオブジェクトを利用します。しかし、再び、それはdiferenceになるだろうことだけ特別な状況なので、小さいです
マルセロ・Ferrazの

1
@ marcelo-ferrazm、about ""はオブジェクトを作成します:いいえ、作成しません。
Henk Holterman、

回答:


272

空のcharのようなものはありません。取得できる最も近いのは'\0'、Unicodeの「null」文字です。それを文字列リテラルに埋め込んだり、それをそれ自体で非常に簡単に表現したりできるとしたら、なぜ別のフィールドが必要なのでしょうか。同様に、「それが混同するのは簡単だ""" "引数は適用されません」'\0'

あなたがそれを使いたい場所の例とそれがより良いと思う理由を与えることができれば、それは役立つかもしれません...


2
\ 0は「バイト配列の終わり」文字ではありませんか?それとも他のものと混同していますか?
Bertvan

5
@Bertvan:バイト配列の最後に文字があるのはなぜですか?はい、「nullで終了する」文字列に使用されます。
ジョンスキート

35
Char.MinValueは '\ 0'より優れています
Aliostad

10
@Aliostad:おもしろいことに、に同様のフィールドがある場合Int32.Zero、リテラル0の代わりにそれを使用しますか?そうでない場合、ここの違いは何ですか?
Jon Skeet

7
@アダム、@ジョン-ベルのコードは何ですか?または、バックスペースをもっとよく考えて考えてください...または、多分、考えずにChar.Backspaceを書く方が良いでしょうか?もう1つの理由-ターミネーターには「0」と書く方が良いと言うが、代わりにChar.Terminatorと言うが、そうではない-タイプミス(完全にコンパイル済み、上記を参照)を作成するのは簡単すぎるが、 Char.Termnator。私がチェックできない生の値を避けるのに十分な理由があります(そのような愚かなタイプミスのために宇宙ミッションは失敗しました)。
greenoldman

87

文字とは異なり、文字は固定サイズの個別のものです。文字列は実際には文字のコンテナです。

したがって、Char.Emptyはそのコンテキストでは実際には意味がありません。charがある場合、それは空ではありません。


3
その通りです。コンテナが空かどうかを尋ねることは理にかなっています。int、float、charが空であることを要求しても意味がありません。
TED

1
@Joe:では、文字列が(空でない)文字のコレクションである場合、文字列はどのように空にすることができますか?おそらく愚かで申し訳ありません...
user1477388

9
文字列は個々のオブジェクトではないので、それはコレクションです。岩のバケツを考えてください。空の岩は持てません。しかし、私は空のバケツを持つことができます。
Joe

2
「charはプリミティブの値型であり、stringは非プリミティブの参照型」と表現します。
samis 2013

3
これが本当の答えです。
Gandalf458 2017


28

Char.MinValue'\ 0'と同じように機能するものを使用します。ただし、と同じではないことに注意してくださいString.Empty


ありがとう、これまで見たことがない。myString.Replace( 'c'、Char.MinValue)で機能するかどうか知っていますか?私はそれを試してみる必要があります。
Joan Venge、2010


12

文字列全体が必要ない場合は、遅延実行を利用できます。

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

複数のキャラクターを組み合わせることもできます...

string veryLongText = "abcdefghijk...";

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

...そして最初の7文字だけが評価されます:)

編集:または、さらに良い:

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

とその使用法:

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

@Joan:ありがとう... "Genius"でも少し誇張されています:P(removeCharsが大きな配列になるときのパフォーマンスはわかりません...)
Notoriousxl

1
昨日忘れました:結果変数「firstFiveCharsWithoutCsAndDs」の使用方法に注意してください。別の "yield"メソッド(LINQのメソッドなど)に渡したくない場合は、 "Take(5)"の直後に ".ToArray()"を呼び出します。それ以外の場合は、 "RemoveChars + Take" "従来の"方法で変数にアクセスするたびに(たとえば、 "Count()"を呼び出すたびに、または "yield return"なしでforeachでトラバースするときに)チェーンが実行されます
Notoriousxl

+1いい考え。しかし、これは基本的なアプローチほど保守可能または効率的になることはできません:)
nawfal

1
@nawfal効率的には正しいですが、myString.Except( "c")はmyString.Replace( 'c'、 '')よりも宣言的だと思います(Pはかなり適切にスケーリングされます:myString.Except( "aeiou"))
Notoriousxl

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

.Replaceメソッドには文字列パラメーターを受け取るオーバーロードがあるため、これは文字を削除するのに特にエレガントではありません。しかし、これはキャリッジリターン、ラインフィード、タブなどを削除するために機能します。この例では、タブ文字を削除します。

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

6

同じ理由がありませんint.Empty。コンテナは空にすることができます。スカラー値はできません。0(空ではない)を意味する場合は、を使用します'\0'。もしあなたが意味するならnull、それからnull:) を使用してください


2
charはValueTypeであるため、nullは使用できません。charを使用する必要がありますか?nullを割り当てることができるようにします。
Femaref

あなたはそれをnullableにする必要があります。私の答えを参照してください
paquetp

5

charは値型であるため、その値をnullにすることはできません。(Nullableコンテナーにラップされていない限り)。

nullにすることはできないため、inにはいくつかの数値コードが含まれ、各コードはいくつかの文字にマップされます。


4

あなたの質問への答えではありませんが、デフォルトを示すためにcharあなたはちょうど使うことができます

default(char)

これはと同じchar.MinValueで、次にと同じ\0です。空の文字列などの場合は使用しないでください。


1

最初の質問に答えませんか?しかし、特定の問題については、文字の代わりに文字列を使用できますよね?:

myString.Replace("c", "")

それをしたくない理由はありますか?


1

削除したい文字を除いて、文字列を文字ごとに再構築することもできます。

これを行う拡張メソッドは次のとおりです。

    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;
    }

滑らかでも派手でもありませんが、うまく機能します。

次のように使用します。

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

StringBuilderforを使用しresultます。なぜ包まないのreturn s.Replace(charsToRemove,"");
aloisdgがcodidact.comに移動2016

1

特定の条件を満たす文字を削除したい場合は、これを使用できます。

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

(これにより、ストリングに大文字のみが残ります。)

つまり、文字列をとして「使用」し、文字列にIEnumerable<char>変更を加えてから、上記のように文字列に戻すことができます。

繰り返しになりますが、これはラムダ式が原因で特定の文字を削除できるだけでなく、ラムダ式を次のように変更した場合でも削除できますc => c != 't'


0

Microsoftがファイルの開始(少なくともXML)に追加する魔法のキャラクターであるBOMはどうですか?


ここでのウィキペディアの表現はかなり残念です。BOMはこのコンテキストではキャラクターではありません。そして、あなたの質問は正確に何ですか?:)
bzlm 2010年

@onemach、それで、myString.Replace ('c', '')によって達成できるかどうかmyString.Replace ('c', UTF_BOM)。それから私は、答えは「どのようにだと思いませんについて...」。
bzlm 2012

0

文字列内の空の文字を削除したい場合は、次のように機能します。必要なデータ型表現に変換してください。ありがとう、

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

C#言語に関しては、以下はあまり意味がありません。そして、これは質問に対する直接の答えではありません。しかし、野鳥は私のビジネスシナリオの1つで私がやったことです

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

nullそしてwhite space私のプロジェクトでさまざまなビジネスフローを持っていました。データベースに挿入empty stringするときに、空白の場合はデータベースに挿入する必要があります。


0

これはかなり古いことを知っていますが、ファイル名を安全にするために複数の置換を行う必要があるという問題が最近発生しました。まず、最新の.NET string.Replace関数では、nullは空の文字と同等です。とは言っても、.Netに欠けているのは、配列内の任意の文字を目的の文字に置き換える単純な置き換えすべてです。以下のコードを自由に参照してください(テスト用にLinqPadで実行)。

// 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

文字列から文字をブランケット削除する最も簡単な方法は、それをトリムすることです

cl = cl.Trim(' ');

文字列内のすべてのスペースを削除します


これは、use .Replace( 'c'、 '')を使用して他の空白を削除する欠点がある場合に役立ちます。しかし、それは与えられた他の多くの答えよりも役立ちます。

1
いいえ、これは間違いです!トリムでは、文字列の最初と最後から文字を削除するだけで、途中ではありません
userSteve
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.