Mengapa tidak ada Char.Empty seperti String.Empty?

259

Apakah ada alasan untuk ini? Saya bertanya karena jika Anda perlu menggunakan banyak karakter kosong maka Anda masuk ke situasi yang sama seperti ketika Anda menggunakan banyak string kosong.

Sunting: Alasan penggunaan ini adalah ini:

myString.Replace ('c', '')

Jadi hapus semua contoh 'c's dari myString.

Joan Venge
sumber
1
Ya saya menggunakan kata itu karena tidak ada kata yang lebih baik. yaitu cara yang direkomendasikan untuk menggunakan String.Empty bukannya "".
Joan Venge
3
Jika Anda khawatir tentang kesalahan ketik yang tidak sengaja '' kadang-kadang, mengapa tidak sekadar membungkus fungsionalitas dalam metode ekstensi di sepanjang baris RemoveAll(this string s, params char[] toRemove)? Maksudnya akan dikomunikasikan dengan jelas dan Anda tidak akan mengambil risiko salah ketik.
bzlm
12
@ Henk - Satu-satunya alasan saya menggunakan string.Empty adalah karena saya menemukan objek nol yang disediakan oleh Empty menyatakan niat lebih baik daripada kutipan kosong. Kutipan kosong bisa dihasilkan dari masalah penggabungan, atau pemikiran yang ceroboh, atau bisa juga maksud sebenarnya dari kode itu, sedangkan Kosong secara eksplisit memberi tahu saya bahwa pengembang bermaksud agar string itu tidak memiliki data.
Ritch Melton
3
Ada perbedaan antara "" dan string. Keluaran. Bukan berarti siapa pun peduli, sungguh, "" tetapi menciptakan sebuah objek, sedangkan string.Empty memanfaatkan yang sudah dibuat. Tetapi sekali lagi, itu sangat kecil, bahwa hanya situasi khusus yang akan membuat perbedaan
marcelo-ferraz
1
@ marcelo-ferrazm, tentang ""membuat objek : Tidak, tidak.
Henk Holterman

Jawaban:

272

Tidak ada yang namanya char kosong. Yang paling dekat Anda dapatkan adalah '\0', karakter Unicode "null". Mengingat bahwa Anda dapat menanamkan itu dalam string literal atau mengekspresikannya sendiri dengan sangat mudah, mengapa Anda ingin bidang yang terpisah untuknya? Sama-sama, argumen " mudah membingungkan ""dan " "" tidak berlaku '\0'.

Jika Anda bisa memberikan contoh di mana Anda ingin menggunakannya dan mengapa Anda pikir itu akan lebih baik, itu mungkin membantu ...

Jon Skeet
sumber
2
Bukankah karakter \ 'akhir dari byte array'-nya? Atau apakah saya bingung dengan hal lain?
Bertvan
5
@ Birvan: Mengapa ada karakter di akhir array byte ? Ini digunakan untuk string "null terminated", ya.
Jon Skeet
35
Char.MinValue lebih baik daripada '\ 0'
Aliostad
10
@ Aliliad: Tidak tertarik, jika ada bidang serupa untuk Int32.Zero, apakah Anda akan menggunakannya sebagai ganti dari 0 literal? Jika tidak, apa bedanya di sini?
Jon Skeet
7
@ Adam, @ Jon - apa kode untuk bel? Atau mundur lebih baik, pikirkanlah ... Atau mungkin alih-alih berpikir itu lebih baik untuk menulis Char. Backspace? Alasan lain - Anda mengatakan lebih baik menulis '0' untuk terminator, sebagai gantinya, katakan Char.Terminator, namun tidak - terlalu mudah untuk membuat kesalahan ketik (dikompilasi penuh, lihat di atas), tetapi cobalah menulis Char.Termnator. Ada cukup alasan bagi saya untuk menghindari nilai mentah yang tidak dapat diperiksa (misi ruang angkasa gagal karena kesalahan ketik bodoh seperti itu).
greenoldman
87

A char, tidak seperti string, adalah hal yang diskrit dengan ukuran tetap. Sebuah string benar-benar sebuah wadah karakter.

Jadi, Char.Empty tidak benar-benar masuk akal dalam konteks itu. Jika Anda memiliki char, itu tidak kosong.

Joe
sumber
3
Benar sekali. Masuk akal untuk bertanya apakah sebuah wadah kosong atau tidak. Tidak masuk akal untuk meminta int atau float atau char kosong.
TED
1
@ Jo: Lalu bagaimana string bisa kosong jika string adalah kumpulan (tidak kosong) karakter? Mungkin bodoh, maaf ...
user1477388
9
Karena string bukan objek individual, itu adalah koleksi. Pikirkan ember batu. Saya tidak dapat memiliki batu yang kosong. Tapi saya bisa punya ember kosong.
Joe
2
Saya akan menyebutnya sebagai "char adalah tipe nilai primitif, dan string adalah tipe referensi non-primitif".
samis
3
Inilah jawaban sebenarnya.
Gandalf458
31

Tidak ada yang namanya karakter kosong. Itu selalu mengandung sesuatu . Bahkan '\ 0' adalah karakter.

Philippe Leybaert
sumber
28

Gunakan Char.MinValueyang berfungsi sama dengan '\ 0'. Tapi hati-hati itu tidak sama dengan String.Empty.

Aliostad
sumber
Terima kasih, belum pernah melihat itu sebelumnya. Apakah Anda tahu jika itu berfungsi di myString.Replace ('c', Char.MinValue)? Saya harus mencobanya.
Joan Venge
19

Anda dapat menggunakan karakter yang dapat dibatalkan .

char? c
paquetp
sumber
Ini memungkinkan ''? Atau hanya nol?
Joan Venge
Dalam kasus Anda, Anda bisa melakukan ini: myString.Replace ("c", (c == null? "": C.ToString ()))
paquetp
12

Jika Anda tidak membutuhkan seluruh string, Anda dapat memanfaatkan eksekusi yang tertunda:

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

Anda bahkan dapat menggabungkan beberapa karakter ...

string veryLongText = "abcdefghijk...";

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

... dan hanya 7 karakter pertama yang akan dievaluasi :)

Sunting: atau, lebih baik lagi:

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

dan penggunaannya:

        var veryLongText = "abcdefghijk...";
        IEnumerable<char> firstFiveCharsWithoutCsAndDs = veryLongText
            .RemoveChars('c', 'd')
            .Take(5)
            .ToArray(); //to prevent multiple execution of "RemoveChars"
Notoriousxl
sumber
@ Joan: terima kasih ... bahkan jika "Genius" itu agak berlebihan: P (Saya tidak tahu tentang kinerjanya saat melepasChars akan menjadi array yang besar ...)
Notoriousxl
1
Kemarin saya lupa: perhatikan bagaimana Anda menggunakan variabel hasil "firstFiveCharsWithoutCsAndDs". Jika Anda tidak ingin meneruskannya ke metode "hasil" lainnya (seperti metode LINQ), segera panggil ".ToArray ()" setelah "Take (5)" ... ... jika tidak, "RemoveChars + Take" rantai akan dieksekusi setiap kali Anda mengakses variabel dengan cara "tradisional" (misalnya, setiap Anda memanggil "Hitungan ()" di atasnya, atau ketika Anda melewatinya dalam foreach tanpa "hasil pengembalian")
Notoriousxl
+1 pemikiran yang bagus. tetapi ini tidak bisa dipertahankan atau seefisien pendekatan dasar :)
nawfal
1
@nawfal efisiensi-bijaksana Anda benar, tapi saya pikir bahwa myString.Except ("c") lebih deklaratif daripada myString.Replace ('c', ''): P (dan ini berskala cukup baik: myString.Except ( "aeiou"))
Notoriousxl
7
myString = myString.Replace('c'.ToString(), "");

OK, ini tidak terlalu elegan untuk menghapus huruf, karena metode .Replace memiliki kelebihan yang mengambil parameter string. Tapi ini berfungsi untuk menghapus carriage return, feed garis, tab, dll. Contoh ini menghilangkan karakter tab:

myString = myString.Replace('\t'.ToString(), "");
Mike Taverne
sumber
6

alasan yang sama tidak ada int.Empty. Wadah bisa kosong. Nilai skalar tidak bisa. Jika Anda berarti 0 (yang tidak kosong), maka gunakan '\0'. Jika maksud Anda null, maka gunakan null:)

sepuluh empat
sumber
2
null tidak dimungkinkan karena char adalah ValueType. Anda harus menggunakan char? untuk dapat menetapkan nol untuk itu.
Femaref
Anda bisa membuatnya nullable. lihat jawaban saya
paquetp
5

Char adalah tipe nilai, jadi nilainya tidak boleh nol. (Kecuali jika dibungkus dalam wadah Nullable).

Karena tidak boleh nol, dalam berisi beberapa kode numerik dan setiap kode dipetakan ke beberapa karakter.

epotter
sumber
4

Bukan jawaban untuk pertanyaan Anda, tetapi untuk menunjukkan default, charAnda hanya dapat menggunakannya

default(char)

yang sama dengan char.MinValueyang pada gilirannya sama dengan \0. Seseorang seharusnya tidak menggunakan jika untuk sesuatu seperti string kosong.

nawfal
sumber
1

Tidak menjawab pertanyaan pertama Anda - tetapi untuk masalah spesifik yang Anda miliki, Anda bisa menggunakan string bukan karakter, kan ?:

myString.Replace("c", "")

Ada alasan mengapa Anda tidak ingin melakukan itu?

Ian Grainger
sumber
1

Anda juga dapat membangun kembali karakter string Anda dengan karakter, tidak termasuk karakter yang ingin Anda singkirkan.

Inilah metode ekstensi untuk melakukan ini:

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

Itu tidak licin atau mewah, tetapi bekerja dengan baik.

Gunakan seperti ini:

string newString = "My_String".RemoveAny("_"); //yields "MyString"
C. Tewalt
sumber
Gunakan StringBuilderuntuk result. Kenapa tidak dibungkus return s.Replace(charsToRemove,"");?
aloisdg pindah ke codidact.com
1

Jika Anda ingin menghapus karakter yang memenuhi kondisi tertentu, Anda dapat menggunakan ini:

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

(Ini hanya akan meninggalkan karakter huruf besar dalam string.)

Dengan kata lain, Anda dapat "menggunakan" string sebagai IEnumerable<char>, membuat perubahan padanya dan kemudian mengubahnya kembali ke string seperti yang ditunjukkan di atas.

Sekali lagi, ini memungkinkan untuk tidak hanya menghapus char tertentu karena ekspresi lambda, meskipun Anda dapat melakukannya jika Anda mengubah ekspresi lambda seperti ini: c => c != 't'.

Florien
sumber
0

Bagaimana dengan BOM , karakter ajaib yang ditambahkan Microsoft untuk memulai file (setidaknya XML)?

Arto Viitanen
sumber
Kata-kata di Wikipedia di sini sangat disayangkan; BOM bukan karakter dalam konteks ini. Dan apa pertanyaan Anda sebenarnya? :)
bzlm
@monemach, jadi, apakah myString.Replace ('c', '')bisa diraih oleh myString.Replace ('c', UTF_BOM). Maka saya akan mengatakan jawabannya adalah "bagaimana tidak tentang ...".
bzlm
0

jika Anda ingin menghapus char kosong di string berikut ini akan bekerja, cukup konversikan ke representasi tipe data yang Anda inginkan. Terima kasih,

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

        }

    }
Alexander Zaldostanov
sumber
0

Dalam hal bahasa C #, yang berikut ini mungkin tidak masuk akal. Dan ini bukan jawaban langsung untuk pertanyaan itu. Tetapi unggas adalah apa yang saya lakukan dalam salah satu skenario bisnis saya

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

The nulldan white spacebisnis memiliki berbagai mengalir dalam proyek saya. Saat memasukkan ke dalam basis data, saya harus memasukkan empty stringke basis data jika itu adalah ruang putih.

LCJ
sumber
0

Saya tahu ini cukup lama, tetapi saya mengalami masalah baru-baru ini karena harus melakukan beberapa penggantian untuk membuat nama file aman. Pertama, dalam fungsi .NET string.Replace null terbaru adalah setara dengan karakter kosong. Karena itu, apa yang hilang dari .Net adalah penggantian sederhana semua yang akan mengganti karakter apa pun dalam array dengan karakter yang diinginkan. Silakan merujuk kode di bawah ini (berjalan di LinqPad untuk pengujian).

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

    }

}
Jim
sumber
-3

menggunakan

myString.Replace ("c", "")
Chintan
sumber
2
Ini adalah duplikat jawaban dari 2013 oleh Ian Grainger.
Joe Gayetty
-3

Cara termudah untuk menghapus karakter dari string adalah dengan Trim

cl = cl.Trim(' ');

Menghapus semua spasi dalam sebuah string

MrSmudge
sumber
Ini berguna jika seseorang ingin menggunakan use .Replace ('c', '') dengan sisi negatifnya menghapus spasi putih lainnya. Tetapi ini lebih membantu daripada banyak jawaban lain yang diberikan.
Jan
1
Tidak, ini salah! Trim hanya menghapus karakter dari awal dan akhir string yang tidak di tengah
userSteve