为什么新的String(“Hello”)在C#中无效?

时间:2011-09-30 21:17:14

标签: c# .net string constructor

制作

背后的逻辑/原因是什么?
String s= new String("Hello World");

C#中是非法的? 错误是

  

`string.String(char *)'的最佳重载方法匹配有一些无效的参数

我对API文档不感兴趣,我感兴趣的是为什么这是非法的。

是因为汇集静态字符串?像Java池整数(-128)到整数(127)与可怕的结果? (当然还有字符串)

9 个答案:

答案 0 :(得分:11)

使用构造函数根据另一个现有字符串创建一个新字符串是没有意义的 - 这就是没有允许这样的构造函数重载的原因。只是做

string s = "Hello World";

答案 1 :(得分:8)

因为字符串是不可变的,并且对它们的构造方式有语言支持。

在您的示例中,由于您使用的是字符串文字,因此会被实习。任何从它创建的复制字符串最终都会与实习池完全相同。

答案 2 :(得分:6)

它是.NET,而不是C#。查看System.String的构造函数 - none接受System.String

因为你不能用int构造一个字符串,所以它是“非法的”。

string x = new String(1);

Raymond Chen

答案“为什么不存在此功能?”通常是“默认情况下功能不存在。有人必须实现它们。”


我的猜测是每次有人坐下来实现这个构造函数。他们考虑了String.ToString的实现,并确定构造函数在逻辑上会破坏该方法。

答案 3 :(得分:2)

它会给人一种克隆字符串的印象,但字符串是不可变的。

答案 4 :(得分:2)

字符串是不可变的,直到你开始搞乱不安全的代码,因此语言设计者选择不添加在正常使用中 的功能。这并不是说在某些情况下它不会派上用场。

如果你这样做:

string a = "foobar";
string b = a;
Mutate(a, "raboof");
Console.WriteLine("b={0}", b);

其中:

unsafe void Mutate(string s, string newContents)
{
    System.Diagnostics.Debug.Assert(newContents.Length == s.Length);
    fixed (char* ps = s)
    {
        for (int i = 0; i < newContents.Length; ++i)
        {
            ps[i] = newContents[i];
        }
    }
}

你可能会惊讶地知道即使字符串&#39; a&#39;是一个突变的输出将是:

b=raboof

在这种情况下,我想写一下:

string a = "foobar";
string b = new String(a);
Mutate(a, "raboof");
Console.WriteLine("b={0}", b);

期待看到如下输出:

b=foobar

但是你不能,因为它不是System.String实现的一部分。

我认为这个设计决策的合理理由是任何人都能够轻松地编写类似于不安全的Mutate方法的东西,它也能够实现克隆字符串的方法。

答案 5 :(得分:0)

您尝试使用的构造函数包含...

  

指向以null结尾的Unicode字符数组的指针

...而不是字符串。

(见http://msdn.microsoft.com/en-us/library/aa331864(v=VS.71).aspx

答案 6 :(得分:0)

让Eric Lipperts评论可见:

必须在成本效益的基础上证明功能。有什么好处可以证明成本合理?如果没有任何好处可以证明成本合理,那么仅仅从经济角度来看,我们有更好的事情要做,而不是设计,指定,实施,测试,记录和维护一个没有人使用或需要的构造函数,这应该是非法的。

答案 7 :(得分:0)

在我结束时,我明白了:

  

`string.String(char [])'的最佳重载方法匹配有一些无效的参数

可以在发布时键入“char *”代替“char []”。

也许这与我们对文字的历史性理解有关。在C#之前,用引号括起来的值(如“astringvalue”)可以视为字符指针。但是在C#中,“astringvalue”只是string类的一个对象。声明:

String s= new String("Hello World");

意味着创建一个String类的对象并调用其构造函数。编译器检查constructors available for string class列表。它找不到任何可以接受字符串对象的构造函数(“Hello world”)。与任何其他情况一样,编译器最好地猜测哪个是重载方法列表中的“最接近”方法 - 在这种情况下,假设字符串值“Hello world”最接近字符数组(char [] ) - 并告诉你你的“Hello world”(你传递的值)是“char []”的无效值。

答案 8 :(得分:0)

在我看来,基本的区别在于.NET和JAVA中的“按引用传递”和“按值传递”。

导致Java中的design pattern,原因可能是

  

用于复制同一类对象的构造函数。

在.NET中,您不需要这样的构造函数来复制/克隆字符串,因为它可以通过以下方式(直接)执行,

'String test = txtName.Text;'

这是我对.net和java的理解。

我希望我能够给出正确的推理。

谢谢和问候

Harsh Baid