开发者

Why is new String("Hello") invalid in C#?

开发者 https://www.devze.com 2023-04-10 00:51 出处:网络
What is the logic/reason behind making String s= new String(\"Hello World\"); Illegal in C#? The error is

What is the logic/reason behind making

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

Illegal in C#? The error is

开发者_运维技巧

The best overloaded method match for `string.String(char*)' has some invalid arguments

I'm not interested in the API docs, I am interested in why this is illegal.

Is is because of pooling static strings? like Java pools Integer(-128) to Integer(127) with horrendous results? ( of course strings too )


It would be rather pointless to use the constructor to create a new string based on another existing string - that's why there is no constructor overload that allows this. Just do

string s = "Hello World";


Because strings are immutable and have language support in how they are constructed.

In your example, since you are using a string literal, it will get interned. Any copied string that would have been created from it would end up being the same exact reference, as it would come from the intern pool.


It's .NET, not C#. Look at the constructors for System.String - none accept a System.String

So it's "illegal" for the same reason you can't construct a string with an int.

string x = new String(1);

Raymond Chen

The answer to "Why doesn't this feature exist?" is usually "By default features don't exist. Somebody has to implement them."


My guess is that every time someone sat down to implement this constructor. They thought about String.ToString's implementation and determined the constructor would logically undermine that method.


It would give the impression that the string is being cloned, but strings are immutable.


A string is immutable until you start messing with unsafe code, so the language designers chose not to add a feature that isn't needed in normal usage. That is not to say it wouldn't be handy in certain situations.

If you do this:

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

where:

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

You may be surprised to know that even though string 'a' is the one that was mutated the output will be:

b=raboof

In this situation one would like to write:

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

And expect to see output like:

b=foobar

But you can't, because it is not part of the implementation of System.String.

And I guess a reasonable justification for that design decision is that anyone comfortable writing something like the unsafe Mutate method is also capable of implementing a method to clone a string.


The constructor you are trying to use takes in...

A pointer to a null terminated array of Unicode characters

...rather than a String.

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


Just to make Eric Lipperts comment visible:

Features have to be justified on a cost-benefit basis. What's the benefit that justifies the cost? If there's no benefit that justifies the cost then it should be illegal simply on the economic grounds that we have better things to do than to design, specify, implement, test, document and maintain a constructor that no one uses or needs.


At my end, I get this:

The best overloaded method match for `string.String(char[])' has some invalid arguments

May be you typed "char *" in place of "char[]" while posting.

Perhaps this has got to do with our historic understanding of literals. Prior to C#, a value enclosed in quotes (like "astringvalue") could be treated as a character pointer. However in C# "astringvalue" is just an object of type string class. The statement:

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

would imply create an object of type String class and invoke its constructor. The compiler checks the list of constructors available for string class. It cannot find any constructor that could accept a string object ("Hello world"). Like in any other situation, the compiler makes a best guess of which is the "closest" method from the list of overloaded methods - in this case, assumes a string value "Hello world" to be closest to a character array (char []) - and tells you that your "Hello world" (value that you passed) is an invalid value for "char []".


In my opinion, The basic difference is the 'Pass by Reference' and 'Pass by Value' in .NET and JAVA.

Leading to a design pattern in Java, for a reason which may be

A constructor for copying an object of the same class.

In .NET you don't require such constructor to copy/clone the string because it can do it in following way (directly),

'String test = txtName.Text;'

This is my understanding of .net and java.

I hope I was able to give proper reasoning.

Thanks and Regards

Harsh Baid

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号