Почему новая строка («Hello») недопустима в C #? - PullRequest
15 голосов
/ 01 октября 2011

Какова логика / причина создания

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

Незаконно в C #? Ошибка

Наилучшее совпадение перегруженного метода для `string.String (char *) 'имеет недопустимые аргументы

Меня не интересуют документы API, меня интересует, почему это незаконно.

Это из-за объединения статических строк? как Java объединяет Integer (-128) в Integer (127) с ужасными результатами? (конечно же струны тоже)

Ответы [ 9 ]

11 голосов
/ 01 октября 2011

Было бы довольно бессмысленно использовать конструктор для создания новой строки на основе другой существующей строки - поэтому нет перегрузки конструктора, которая позволяла бы этоПросто сделай

string s = "Hello World";
8 голосов
/ 01 октября 2011

Поскольку строки неизменяемы и имеют языковую поддержку в том, как они построены.

В вашем примере, поскольку вы используете строковый литерал, он будет интернирован. Любая скопированная строка, которая была бы создана из нее, в итоге оказалась бы такой же точной ссылкой, как и из внутреннего пула.

6 голосов
/ 01 октября 2011

Это .NET, а не C #. Посмотрите на конструкторы для System.String - никто не принимает System.String

Так что это "незаконно" по той же причине, по которой вы не можете создать строку с целым числом.

string x = new String(1);

Раймонд Чен

Ответ на вопрос «Почему эта функция не существует?» обычно «По умолчанию функции не существуют. Кто-то должен их реализовать».


Я предполагаю, что каждый раз, когда кто-то садился за реализацию этого конструктора. Они подумали о реализации String.ToString и решили, что конструктор логически подорвет этот метод.

2 голосов
/ 24 марта 2015

Строка неизменна , пока вы не начнете связываться с небезопасным кодом , поэтому разработчики языка решили не добавлять функцию, которая не нужна при обычном использовании .Это не значит, что в определенных ситуациях это не пригодится.

Если вы сделаете это:

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

Вы можете быть удивленычтобы знать, что , хотя строка 'a' является мутировавшей , на выходе получится:

b=raboof

В этой ситуации нужно написать:

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

И ожидайте увидеть вывод вроде:

b=foobar

Но вы не можете, потому что он не является частью реализации System.String.

И я предполагаю разумное обоснованиетак как это дизайнерское решение заключается в том, что любой, кому удобно писать что-то вроде небезопасного метода Мутата, также способен реализовать метод для клонирования строки.

2 голосов
/ 01 октября 2011

Создается впечатление, что строка клонируется, но строки неизменны.

0 голосов
/ 02 октября 2011

На мой взгляд, основным отличием являются «Передача по ссылке» и «Передача по значению» в .NET и JAVA.

Приводит к шаблону проектирования в Java по причине, которая может быть

Конструктор для копирования объекта того же класса.

В .NET вам не требуется, чтобы такой конструктор копировал / клонировал строку, потому что он может делать это следующим образом (напрямую),

'String test = txtName.Text;'

Это мое понимание .net и java.

Надеюсь, я смог дать правильное обоснование.

Спасибо и С уважением

Harsh Baid

0 голосов
/ 01 октября 2011

В конце я получаю это:

Наилучшее совпадение перегруженного метода для `string.String (char []) 'имеет недопустимые аргументы

Может быть, вы набрали «char *» вместо «char []» во время публикации.

Возможно, это связано с нашим историческим пониманием литералов. До C # значение, заключенное в кавычки (например, «astringvalue»), могло рассматриваться как символьный указатель. Однако в C # "astringvalue" это просто объект типа string string. Утверждение:

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

подразумевает создание объекта типа String класса и вызовет его конструктор. Компилятор проверяет список конструкторов , доступных для строкового класса . Он не может найти конструктор, который мог бы принять строковый объект («Hello world»). Как и в любой другой ситуации, компилятор делает предположение, что это «ближайший» метод из списка перегруженных методов - в этом случае предполагается, что строковое значение «Hello world» наиболее близко к массиву символов (char [] ) - и сообщает вам, что ваш «Hello world» (значение, которое вы передали) является недопустимым значением для «char []».

0 голосов
/ 01 октября 2011

Просто чтобы сделать комментарий Эрика Липпертса видимым:

Функции должны быть обоснованы с точки зрения затрат и выгод. Какая выгода оправдывает стоимость? Если нет никакой выгоды, оправдывающей стоимость, тогда она должна быть незаконной просто по экономическим соображениям, что у нас есть более важные дела, чем разработка, определение, внедрение, тестирование, документирование и поддержка конструктора, который никто не использует или не нуждается.

0 голосов
/ 01 октября 2011

Конструктор, который вы пытаетесь использовать, принимает ...

Указатель на завершенный нулем массив символов Юникода

... вместо строки.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...