为什么没有像String.Empty这样的Char.Empty?


259

是否有一个原因?我问是因为如果您需要使用大量的空字符,那么您会遇到与使用大量的空字符串时相同的情况。

编辑:这种用法的原因是这样的:

myString.Replace ('c', '')

因此,从myString中删除所有'c'实例。


1
是的,我因为缺少更好的词而使用了这个词。即建议使用String.Empty而不是“”的方式。
Joan Venge

3
如果您担心有时会不小心弄错“”,为什么不只是简单地将功能包装在扩展方法RemoveAll(this string s, params char[] toRemove)呢?意图将得到明确传达,您不会冒犯任何错误的风险。
bzlm 2010年

12
@Henk-我使用string.Empty的唯一原因是因为我发现Empty提供的空对象比空引号更好地表达了意图。空引号可能是合并问题或思想混乱所致,也可能是该代码的实际意图,而空引号则明确告诉我开发人员打算使该字符串不包含数据。
里奇·梅尔顿

3
“”和string.Empty之间有区别。并不是每个人都在乎,而是使用“”创建一个对象,而string.Empty使用已经创建的对象。但同样,它是如此之小,以至于只有特殊情况才会有所不同
marcelo-ferraz 2011年

1
@ marcelo-ferrazm,即将""创建一个对象:不,它不会。
Henk Holterman

Answers:


271

没有一个空字符。您可以获得的最接近'\0'的字符是Unicode“空”字符。鉴于您可以将其嵌入到字符串文字中或非常容易地表达它,为什么要为此单独使用一个字段?同样,“很容易混淆""" "”论点不适用'\0'

如果您可以举一个例子说明您想在哪里使用它以及为什么您认为它会更好,那可能会有所帮助...


2
\ 0是否不是“字节数组的末尾”字符?还是我对其他东西感到困惑?
Bertvan'9

5
@Bertvan:为什么字节数组的末尾会有一个字符?是的,它用于“空终止”字符串。
乔恩·斯基特

35
Char.MinValue比'\ 0'好
Aliostad

10
@Aliostad:出于兴趣,如果有类似的字段Int32.Zero,您会使用它代替文字0吗?如果没有,这里有什么区别?
乔恩·斯基特

7
@Adam,@Jon-贝尔的代码是什么?还是想让退格更好,想想……或者也许不认为写Char.Backspace更好?另一个原因-您说最好给终结符写'0',而不是说Char.Terminator,但是事实并非如此-作错字(完全编译,见上文)太容易了,但是尝试写Char.Termnator。我有足够的理由避免使用无法检查的原始值(太空任务由于此类愚蠢的错字而失败)。
greenoldman 2010年

87

与字符串不同,字符是固定大小的离散对象。字符串实际上是字符的容器。

因此,在这种情况下,Char.Empty确实没有任何意义。如果您有一个字符,则不为空。


3
非常正确。询问容器是否为空是有意义的。询问int或float或char是否为空是没有意义的。
TED

1
@Joe:如果字符串是(非空)字符的集合,那么字符串如何为空?可能是愚蠢的,对不起...
user1477388

9
因为字符串不是单个对象,所以它是集合。想想一桶石头。我不能有一块空的石头。但是我可以有一个空桶。

2
我将其表述为“ char是原始类型,值类型,而字符串是非原始类型,引用类型”。
samis 2013年

3
这是真正的答案。
Gandalf458 '17


28

使用Char.MinValue与“ \ 0”相同的功能。但请注意,它与String.Empty


谢谢,以前没看过。您知道它是否在myString.Replace('c',Char.MinValue)中工作吗?我应该试试看。
Joan Venge


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(我不知道在删除Chars时它的性能会变成很大的数组...)
Notoriousxl 2010年

1
昨天我忘记了:请注意如何使用结果变量“ firstFiveCharsWithoutCsAndDs”。如果您不想将其传递给另一个“ yield”方法(如LINQ的方法),请在“ Take(5)”之后立即调用“ .ToArray()” ...否则,请调用“ RemoveChars + Take”链将在您每次以“传统”方式访问变量时执行(例如,每次您在变量上调用“ Count()”,或者在没有“ yield return”的情况下遍历它时都将执行)
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

你应该使它为空。看到我的答案
paquetp 2010年

5

字符是一种值类型,因此其值不能为null。(除非将其包装在可空容器中)。

由于不能为null,因此in中包含一些数字代码,并且每个代码都映射到某个字符。


4

不是您问题的答案,但要表示默认值,char您可以使用

default(char)

与相同,char.MinValue而依次与相同\0。但是,对于诸如空字符串之类的东西,则不应使用。


1

没有回答您的第一个问题-但是对于您遇到的特定问题,您可以只使用字符串而不是char,对吗?

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"

使用StringBuilderresult。为什么不包裹return s.Replace(charsToRemove,"");
aloisdg移至codidact.com,2016年

1

如果要删除满足特定条件的字符,可以使用以下命令:

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

(这将只在字符串中保留大写字符。)

换句话说,您可以将字符串“用作” IEnumerable<char>,对其进行更改,然后将其转换回字符串,如上所示。

同样,这使得不仅去除,因为lambda表达式的特定字符,但你可以这样做,如果你改变了lambda表达式是这样的:c => c != 't'


0

如何BOM,神奇的人物微软添加到启动文件(至少XML)?


维基百科上的措词很不幸。BOM在此上下文中不是字符。您到底要问什么?:)
bzlm

@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#语言而言,以下内容可能没有多大意义。这不是问题的直接答案。但是愚弄是我在一种业务场景中所做的

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

nullwhite space有不同的业务在我的项目流动。插入数据库时​​,empty string如果是空白,则需要插入数据库。


0

我知道这个文件已经很老了,但是最近我遇到了一个问题,必须进行多次替换才能确保文件名的安全。首先,在最新的.NET字符串中。替换函数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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.