Ответ 1
Было бы бессмысленно использовать конструктор для создания новой строки на основе другой существующей строки - поэтому нет никакой перегрузки конструктора, которая позволяет это. Просто сделайте
string s = "Hello World";
Какова логика/причина создания
String s= new String("Hello World");
Недопустимо в С#? Ошибка
Наилучшее перегруженное соответствие метода для `string.String(char *) 'имеет некоторые недопустимые аргументы
Меня не интересуют документы API, меня интересует, почему это незаконно.
Является ли это из-за объединения статических строк? как Java-пулы Integer (-128) для Integer (127) с ужасающими результатами? (конечно же строки)
Было бы бессмысленно использовать конструктор для создания новой строки на основе другой существующей строки - поэтому нет никакой перегрузки конструктора, которая позволяет это. Просто сделайте
string s = "Hello World";
Поскольку строки неизменяемы и имеют языковую поддержку в том, как они создаются.
В вашем примере, поскольку вы используете строковый литерал, он будет интернирован. Любая скопированная строка, которая была бы создана из нее, оказалась бы такой же точной ссылкой, что и исходный пул.
Это .NET, а не С#. Посмотрите на конструкторы для System.String - никто не принимает System.String
Так что это "незаконно" по той же причине, что вы не можете построить строку с int.
string x = new String(1);
Ответ на вопрос "Почему эта функция не существует?" обычно "По умолчанию функции не существуют. Кто-то должен их реализовать".
Я предполагаю, что каждый раз, когда кто-то сел, чтобы реализовать этот конструктор. Они подумали о реализации String.ToString и определили, что конструктор логически подорвет этот метод.
Создается впечатление, что строка клонируется, но строки неизменяемы.
Строка является неизменной , пока вы не начнете возиться с небезопасным кодом, поэтому разработчики языка решили не добавлять функцию, которая не нужна при нормальном использовании. Это не значит, что в определенных ситуациях это не будет удобно.
Если вы это сделаете:
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 также способен реализовать метод клонирования строки.
Конструктор, который вы пытаетесь использовать, берет...
Указатель на нуль-завершенный массив символов Unicode
... а не строка.
(см. http://msdn.microsoft.com/en-us/library/aa331864(v=VS.71).aspx)
Просто, чтобы сделать комментарий Эрика Липперса видимым:
Особенности должны быть оправданы с точки зрения затрат и выгод. Какая польза, которая оправдывает стоимость? Если нет никакой выгоды, которая оправдывала бы стоимость, то она должна быть незаконной просто по экономическим соображениям, что у нас есть лучшие дела, чем создавать, указывать, внедрять, тестировать, документировать и поддерживать конструктор, который никто не использует или не нуждается.
В конце я получаю следующее:
Наилучшее перегруженное соответствие метода для `string.String(char []) 'имеет некоторые недопустимые аргументы
Возможно, вы набрали "char *" вместо "char []" при публикации.
Возможно, это связано с нашим историческим пониманием литералов. До С# значение, заключенное в кавычки (например, значение "astringvalue" ), можно рассматривать как указатель на символ. Однако в С# "astringvalue" - это просто объект типа string. Утверждение:
String s= new String("Hello World");
означало бы создать объект типа String и вызвать его конструктор. Компилятор проверяет список конструкторов доступных для класса строк. Он не может найти конструктор, который мог бы принять строковый объект ( "Hello world" ). Как и в любой другой ситуации, компилятор лучше всего догадывается о том, что является "ближайшим" методом из списка перегруженных методов - в этом случае предполагается, что строковое значение "Hello world" должно быть ближе к массиву символов (char []) - и сообщает вам, что ваш "Hello world" (значение, которое вы передали) является недопустимым значением для "char []".
На мой взгляд, основным отличием является "Pass by Reference" и "Pass by Value" в .NET и JAVA.
В соответствии с шаблоном проектирования на Java, по причине, которая может быть
Конструктор для копирования объекта того же класса.
В .NET вы не требуете, чтобы такой конструктор копировал/клонировал строку, потому что он может делать это следующим образом (напрямую),
'String test = txtName.Text;'
Это мое понимание .net и java.
Надеюсь, я смог дать правильные рассуждения.
Спасибо и с уважением
Harsh Baid