Почему новый Cring ( "Hello" ) недействителен в С#?

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

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

Недопустимо в С#? Ошибка

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

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

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

Ответы

Ответ 1

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

string s = "Hello World";

Ответ 2

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

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

Ответ 3

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

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

string x = new String(1);

Раймонд Чен

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


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

Ответ 4

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

Ответ 5

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

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

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.

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

Ответ 7

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

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

Ответ 8

В конце я получаю следующее:

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

Возможно, вы набрали "char *" вместо "char []" при публикации.

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

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

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

Ответ 9

На мой взгляд, основным отличием является "Pass by Reference" и "Pass by Value" в .NET и JAVA.

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

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

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

'String test = txtName.Text;'

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

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

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

Harsh Baid