Tại sao không có Char.Empty như String.Empty?


259

Có một lý do cho điều này? Tôi đang hỏi bởi vì nếu bạn cần sử dụng nhiều ký tự trống thì bạn sẽ gặp tình huống tương tự như khi bạn sử dụng nhiều chuỗi trống.

Chỉnh sửa: Lý do cho việc sử dụng này là:

myString.Replace ('c', '')

Vì vậy, hãy xóa tất cả các phiên bản của c khỏi myString.


1
Vâng, tôi đã sử dụng từ đó vì thiếu một từ tốt hơn. tức là cách được đề xuất sử dụng String.Empty thay vì "".
Joan Venge

3
Nếu đôi khi bạn lo lắng về việc vô tình nhầm lẫn '', tại sao không chỉ đơn giản là bọc chức năng trong một phương thức mở rộng dọc theo dòng RemoveAll(this string s, params char[] toRemove)? Ý định sẽ được truyền đạt rõ ràng và bạn sẽ không có nguy cơ nhầm lẫn bất cứ điều gì.
bzlm

12
@Henk - Lý do duy nhất tôi sử dụng chuỗi.Empty là vì tôi tìm thấy đối tượng null được cung cấp bởi Empty thể hiện ý định tốt hơn so với trích dẫn trống. Các trích dẫn trống có thể xuất phát từ một vấn đề hợp nhất hoặc suy nghĩ lộn xộn hoặc đó có thể là mục đích thực sự của mã đó, trong khi Empty nói rõ với tôi rằng nhà phát triển dự định chuỗi đó không có dữ liệu.
Ritch Melton

3
Có một sự khác biệt giữa "" và chuỗi.Empty. Thực sự không phải ai cũng quan tâm, nhưng "" tạo ra một đối tượng, trong khi chuỗi.Empty sử dụng một đối tượng đã được tạo. Nhưng một lần nữa, nó quá nhỏ đến nỗi chỉ những tình huống đặc biệt mới tạo nên sự khác biệt
marcelo-ferraz

1
@ marcelo-ferrazm, về việc ""tạo một đối tượng : Không, không.
Henk Holterman

Câu trả lời:


272

Không có thứ gọi là char trống. Gần nhất bạn có thể nhận được là '\0', ký tự "null" Unicode. Cho rằng bạn có thể nhúng nó trong chuỗi ký tự hoặc tự thể hiện nó một cách dễ dàng, tại sao bạn lại muốn có một trường riêng cho nó? Tương tự, các đối số "thật dễ nhầm lẫn """ "" không áp dụng cho '\0'.

Nếu bạn có thể đưa ra một ví dụ về nơi bạn muốn sử dụng nó và tại sao bạn nghĩ nó sẽ tốt hơn, điều đó có thể giúp ...


2
Không phải là \ 0 'kết thúc' của ký tự byte? Hay tôi đang nhầm lẫn với cái gì khác?
Bertvan

5
@Bertvan: Tại sao sẽ có một ký tự ở cuối một mảng byte ? Mặc dù vậy, nó được sử dụng cho các chuỗi "null chấm dứt", vâng.
Jon Skeet

35
Char.MinValue tốt hơn '\ 0'
Aliostad

10
@Aliostad: Không quan tâm, nếu có một lĩnh vực tương tự cho Int32.Zero, bạn sẽ sử dụng nó thay vì nghĩa đen 0? Nếu không, sự khác biệt ở đây là gì?
Jon Skeet

7
@Adam, @Jon - mã cho chuông là gì? Hoặc backspace tốt hơn, suy nghĩ suy nghĩ ... Hoặc có thể thay vì nghĩ rằng tốt hơn là viết Char.Backspace? Một lý do khác - bạn nói rằng tốt hơn là viết '0' cho terminator, thay vào đó, nói Char.Terminator, tuy nhiên không phải vậy - quá dễ để tạo một lỗi đánh máy (được biên dịch đầy đủ, xem ở trên), nhưng hãy thử viết Char.Termnator. Có đủ lý do để tôi tránh các giá trị thô không thể kiểm tra được (các nhiệm vụ không gian thất bại vì lỗi chính tả ngu ngốc như thế).
greenoldman

87

Một char, không giống như một chuỗi, là một thứ rời rạc với kích thước cố định. Một chuỗi thực sự là một thùng chứa ký tự.

Vì vậy, Char.Empty không thực sự có ý nghĩa trong bối cảnh đó. Nếu bạn có một char, nó không trống.


3
Hoàn toàn chính xác. Nó có ý nghĩa để hỏi nếu một container rỗng hay không. Không có nghĩa gì để hỏi một int hoặc float hoặc char là trống rỗng.
TED

1
@Joe: Làm thế nào một chuỗi có thể trống nếu một chuỗi là một tập hợp các ký tự (không trống)? Có lẽ là ngu ngốc, xin lỗi ...
user1477388

9
Bởi vì một chuỗi không phải là các đối tượng riêng lẻ, đó là bộ sưu tập. Hãy nghĩ về một xô đá. Tôi không thể có một tảng đá trống. Nhưng tôi có thể có một cái thùng rỗng.
Joe

2
Tôi sẽ gọi nó là "char là kiểu nguyên thủy, giá trị và chuỗi không phải là kiểu nguyên thủy, kiểu tham chiếu".
samis

3
Đây là câu trả lời thực sự.
Gandalf458

31

Không có thứ gọi là nhân vật trống rỗng. Nó luôn chứa một cái gì đó . Ngay cả '\ 0' là một ký tự.


28

Sử dụng Char.MinValuehoạt động tương tự như '\ 0'. Nhưng hãy cẩn thận nó không giống như String.Empty.


Cảm ơn, chưa từng thấy điều đó trước đây. Bạn có biết nếu nó hoạt động trong myString.Replace ('c', Char.MinValue)? Tôi nên thử.
Joan Venge

19

Bạn có thể sử dụng ký tự nullable .

char? c

Điều này cho phép ''? Hay chỉ là null?
Joan Venge

Trong trường hợp của bạn, bạn có thể làm điều này: myString.Replace ("c", (c == null? "": C.ToString ()))
paquetp

12

Nếu bạn không cần toàn bộ chuỗi, bạn có thể tận dụng việc thực thi bị trì hoãn:

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

Bạn thậm chí có thể kết hợp nhiều nhân vật ...

string veryLongText = "abcdefghijk...";

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

... và chỉ 7 ký tự đầu tiên sẽ được đánh giá :)

EDIT: hoặc, thậm chí tốt hơn:

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

và cách sử dụng của nó:

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

@Joan: cảm ơn ... ngay cả khi "Thiên tài" thì hơi cường điệu: P (Tôi không biết về màn trình diễn của nó khi gỡ bỏ Chars sẽ trở thành một mảng lớn ...)
Notoriousxl

1
Hôm qua tôi đã quên: chú ý đến cách bạn đang sử dụng biến kết quả "firstFiveCharsWithoutCsAndDs". Nếu bạn không muốn chuyển nó sang một phương thức "nhường" khác (như của LINQ), hãy gọi ngay ".ToArray ()" sau "Take (5)" ... nếu không, "RemoveChars + Take" chuỗi sẽ được thực thi mỗi khi bạn truy cập vào biến theo kiểu "truyền thống" (ví dụ: mỗi lần bạn gọi "Count ()" trên nó hoặc khi bạn duyệt qua nó trong một foreach mà không "return return")
Notoriousxl

+1 suy nghĩ tốt. nhưng điều này không thể duy trì hoặc hiệu quả như cách tiếp cận cơ bản :)
nawfal

1
@nawfal hiệu quả-khôn ngoan, bạn đúng, nhưng tôi nghĩ rằng myString.Except ("c") mang tính khai báo nhiều hơn myString.Replace ('c', ''): P (và nó có tỷ lệ khá tốt: myString.Except ( "Aeiou"))
Notoriousxl

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

OK, điều này không đặc biệt thanh lịch để xóa các chữ cái, vì phương thức .Replace có quá tải lấy tham số chuỗi. Nhưng điều này hoạt động để loại bỏ trả về vận chuyển, nguồn cấp dữ liệu, tab, v.v. Ví dụ này loại bỏ các ký tự tab:

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

6

cùng một lý do không có int.Empty. Các thùng chứa có thể trống. Giá trị vô hướng không thể. Nếu bạn có nghĩa là 0 (không trống), thì hãy sử dụng '\0'. Nếu bạn có ý nghĩa null, sau đó sử dụng null:)


2
null là không thể vì char là một ValueType. Bạn sẽ phải sử dụng char? để có thể gán null cho nó.
Femaref

bạn nên làm cho nó vô giá trị xem câu trả lời của tôi
paquetp

5

Một char là một loại giá trị, vì vậy giá trị của nó không thể là null. (Trừ khi nó được bọc trong một thùng chứa Nullable).

Vì nó không thể là null, nên chứa một số mã số và mỗi mã được ánh xạ tới một số ký tự.


4

Không phải là một câu trả lời cho câu hỏi của bạn, nhưng để biểu thị một mặc định, charbạn chỉ có thể sử dụng

default(char)

mà tương tự như char.MinValuelần lượt là giống như \0. Không nên sử dụng nếu cho một cái gì đó như một chuỗi rỗng.


1

Không trả lời câu hỏi đầu tiên của bạn - nhưng đối với vấn đề cụ thể bạn gặp phải, bạn chỉ có thể sử dụng chuỗi thay vì ký tự, phải không?:

myString.Replace("c", "")

Có một lý do bạn sẽ không muốn làm điều đó?


1

Bạn cũng có thể xây dựng lại ký tự chuỗi của mình theo ký tự, ngoại trừ các ký tự mà bạn muốn loại bỏ.

Đây là một phương pháp mở rộng để làm điều này:

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

Nó không trơn tru hay lạ mắt, nhưng nó hoạt động tốt.

Sử dụng như thế này:

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

Sử dụng StringBuildercho result. Tại sao không bọc return s.Replace(charsToRemove,"");?
aloisdg chuyển đến codidact.com

1

Nếu bạn muốn xóa các ký tự thỏa mãn một điều kiện cụ thể, bạn có thể sử dụng:

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

(Điều này sẽ chỉ để lại các ký tự viết hoa trong chuỗi.)

Nói cách khác, bạn có thể "sử dụng" chuỗi như một IEnumerable<char>, thay đổi trên chuỗi và sau đó chuyển đổi lại thành chuỗi như được hiển thị ở trên.

Một lần nữa, điều này cho phép không chỉ loại bỏ một char cụ thể vì biểu thức lambda, mặc dù bạn có thể làm như vậy nếu bạn thay đổi biểu thức lambda như thế này : c => c != 't'.


0

Làm thế nào về BOM , nhân vật ma thuật Microsoft thêm vào để bắt đầu các tệp (ít nhất là XML)?


Các từ ngữ trên Wikipedia ở đây khá đáng tiếc; BOM không phải là một nhân vật trong bối cảnh này. Và câu hỏi của bạn chính xác là gì? :)
bzlm

@onemach, vì vậy, liệu myString.Replace ('c', '')có thể đạt được bằng cách myString.Replace ('c', UTF_BOM). Sau đó, tôi sẽ nói câu trả lời là "làm thế nào không ...".
bzlm

0

nếu bạn muốn sắp xếp chuỗi char trống trong chuỗi sau đây sẽ hoạt động, chỉ cần chuyển đổi sang bất kỳ biểu diễn kiểu dữ liệu nào bạn muốn. cảm ơn,

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

Về ngôn ngữ C #, những điều sau đây có thể không có nhiều ý nghĩa. Và đây không phải là một câu trả lời trực tiếp cho câu hỏi. Nhưng fowlloing là những gì tôi đã làm trong một trong những kịch bản kinh doanh của tôi

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

Các nullwhite spacecó dòng chảy kinh doanh khác nhau trong dự án của tôi. Trong khi chèn vào cơ sở dữ liệu, tôi cần chèn empty stringvào cơ sở dữ liệu nếu nó là khoảng trắng.


0

Tôi biết cái này khá cũ, nhưng tôi đã gặp một vấn đề gần đây với việc phải thực hiện nhiều thay thế để làm cho tên tệp an toàn. Đầu tiên, trong chuỗi .NET mới nhất. Hàm hàm null tương đương với ký tự trống. Phải nói rằng, cái còn thiếu từ .Net là một thay thế đơn giản tất cả sẽ thay thế bất kỳ ký tự nào trong một mảng bằng ký tự mong muốn. Xin vui lòng tham khảo mã bên dưới (chạy trong LinqPad để thử nghiệm).

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

sử dụng

myString.Replace ("c", "")

2
Đây là bản sao câu trả lời từ năm 2013 của Ian Grainger.
Joe Gayetty

-3

Cách dễ nhất để loại bỏ một ký tự khỏi chuỗi là Cắt nó

cl = cl.Trim(' ');

Xóa tất cả các khoảng trắng trong một chuỗi


Điều này hữu ích nếu một người muốn sử dụng .Replace ('c', '') với nhược điểm là loại bỏ các khoảng trắng khác. Nhưng nó hữu ích hơn rất nhiều câu trả lời khác được đưa ra.
Jan

1
Không, điều này là sai! Cắt chỉ xóa các ký tự từ đầu và cuối của một chuỗi không ở giữa
userSteve
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.