#c# #.net #string #constructor
#c# #.net #строка #конструктор
Вопрос:
Какова логика / причина создания
String s= new String("Hello World");
Недопустимо в C #?
Ошибка
Лучший перегруженный метод соответствует `string.String(char *)’ имеет некоторые недопустимые аргументы
Меня не интересуют документы API, меня интересует, почему это незаконно.
Это из-за объединения статических строк? например, Java объединяет целое число (-128) в целое число (127) с ужасающими результатами? (конечно, строки тоже)
Комментарии:
1. Потому что класс string не содержит конструктора, принимающего один строковый аргумент?
2. (В Java есть
new String(String)
конструктор — это особенно полезно для академической игры с «новыми строковыми объектами» и «интернированными строковыми объектами», поскольку строки Java не перегружаются==
… в любом случае, поскольку она есть в Java , почему не в C #? Я надеюсь, что некоторые ответы могут попытаться решить эту проблему, если она адресуема по какой-либо разумной причине [кроме того, что она не была признана полезной / необходимой].)3. Функции должны быть обоснованы с точки зрения затрат и выгод. Какая выгода оправдывает затраты? Если нет никакой выгоды, которая оправдывает затраты, тогда это должно быть незаконным просто по экономическим соображениям, что у нас есть дела поважнее, чем разрабатывать, указывать, внедрять, тестировать, документировать и поддерживать конструктор, который никто не использует или не нуждается.
4. @CaptainGiraffe: Пожалуйста, не соглашайтесь! В чем убедительная выгода для клиентов от «создания новой ссылки» на строку? Бывали дни, когда мне очень нужно было «создать клонированную копию состояния этого IEnumerator», но я ни разу не сказал себе: «Мне нужно иметь две строки, которые идентичны во всех отношениях, кроме их управляемого адреса, тем самым гарантированно занимая в два раза больше места, чем необходимов памяти». Я не вижу здесь преимущества.
5. @pst: Каким образом «потому что у Java есть это» каким- либо образом оправдывает функцию в C #? Возможности в C # оправданы их неоспоримыми преимуществами для наших клиентов. (И я отмечаю, что наиболее очевидная особенность C #, которая существует «потому, что она есть в Java» — ковариация массива — глубоко нарушена и вызывает серьезные проблемы с производительностью и корректностью.) Я полагаю, у разработчиков Java была какая-то причина добавить эту функцию; спросите их, хотите ли вы получить их объяснение. Я не эксперт по Java, поэтому понятия не имею, почему в Java есть такая функция.
Ответ №1:
Было бы довольно бессмысленно использовать конструктор для создания новой строки на основе другой существующей строки — вот почему нет перегрузки конструктора, которая позволяет это. Просто сделайте
string s = "Hello World";
Комментарии:
1. Итак, почему в Java существует такая конструкция? 😉
2. Я думал, что конструкторы копирования полезны.
3. @Captain Giraffe Какой смысл копировать объект, который никогда не может быть изменен? 🙂
4. @supercat: вы имеете в виду строковую переменную , а не строку. Переменная, конечно, может указывать на другую строку, но сама строка остается неизменной
5. @Captain Giraffe
==
(как и все операторы) не является полиморфным.object.==(object)
является идентификатором объекта. Однакоstring.==(string)
это равенство значений. Это резко контрастирует с Java (которая не имеет==
перегрузки).
Ответ №2:
Потому что строки неизменяемы и имеют языковую поддержку в том, как они создаются.
В вашем примере, поскольку вы используете строковый литерал, он будет интернирован. Любая скопированная строка, которая была бы создана из нее, в конечном итоге будет такой же точной ссылкой, как и из пула стажеров.
Комментарии:
1. Почему неизменность строк вообще вступает в игру?
2. Вы создаете строку из строки — обе идентичны и не могут быть изменены. В чем смысл? Просто используйте исходную строку.
3. Аргумент объединения — единственный надежный аргумент, который я нашел до сих пор. Спасибо.
Ответ №3:
Это .NET, а не C #. Посмотрите на конструкторы для System .Строка — нет принимает систему.Строка
Так что это «незаконно» по той же причине, по которой вы не можете создать строку с помощью int .
string x = new String(1);
Ответ на вопрос «Почему эта функция не существует?» обычно звучит так: «По умолчанию функции не существуют. Кто-то должен их реализовать «.
Я предполагаю, что каждый раз, когда кто-то садился за реализацию этого конструктора. Они подумали о строке.Реализация toString и определила, что конструктор логически подорвет этот метод.
Комментарии:
1. Я хочу сказать, что никто не делал это незаконным. Они просто не указали конструктор, который вы ожидаете увидеть там. Вопрос «Почему», который вы должны задать, звучит так: «Почему вы ожидаете, что она будет там?». Если это потому, что вы пришли из мира Java, тогда добро пожаловать в .Net — здесь все по-другому.
2. Нет, если что, я из мира c . Но я ценю приветствие =)
3. 1 Не обижайтесь на остальных, но я считаю, что этот пост заслуживает большего количества голосов, чем остальные
Ответ №4:
Это создало бы впечатление, что строка клонируется, но строки неизменяемы.
Комментарии:
1. Они не обязательно ортогональны, но сильно связаны.
Ответ №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.Строка.
И я полагаю, разумным оправданием этого дизайнерского решения является то, что любой, кому удобно писать что-то вроде метода unsafe Mutate, также способен реализовать метод для клонирования строки.
Комментарии:
1. Даже если вы не используете небезопасный код, есть некоторые ситуации, в которых может быть полезно иметь строку, которая, как известно, не является ссылочной — равной любой другой строке, которая может существовать где угодно во вселенной — для проверки поведения кода интернирования строки, если ничего другого. Как уже было сказано, тот факт, что повторные вызовы для
new String(' ', 0)
получения одного и того же экземпляра означают, что неясно, что повторные вызовыnew String("Fred")
не будут делать то же самое.2. Достаточно верно в отношении гипотетического поведения, которое будет иметь конструктор String (string). Тем больше причин написать свой собственный небезопасный метод клонирования. 🙂
3. Лично я так думаю . NET должен был либо иметь конструкторы типа класса, которые всегда выдают новые экземпляры объектов, либо заставлять их вызывать фабричные методы, которые имели бы возможность возвращать кэшированные экземпляры. Я могу оценить, что в большинстве случаев совместное использование экземпляров строк нулевой длины было бы неплохо, но правильным способом справиться с этим было бы иметь
String.Repeat(char,int)
перегрузку, спецификация которой указывала, что можно свободно использовать экземпляры string для любых комбинаций параметров параметров, которые казались целесообразными.
Ответ №6:
Конструктор, который вы пытаетесь использовать, принимает…
Указатель на массив символов Unicode, завершающийся нулем
…вместо строки.
(См http://msdn.microsoft.com/en-us/library/aa331864 (v= VS.71).aspx)
Ответ №7:
Просто чтобы сделать видимым комментарий Эрика Липпертса:
Функции должны быть обоснованы с точки зрения затрат и выгод. Какая выгода оправдывает затраты? Если нет никакой выгоды, которая оправдывает затраты, тогда это должно быть незаконным просто по экономическим соображениям, что у нас есть дела поважнее, чем разрабатывать, указывать, внедрять, тестировать, документировать и поддерживать конструктор, который никто не использует или не нуждается.
Ответ №8:
С моей стороны, я получаю это:
Лучший перегруженный метод соответствует `string.String(char[])’ имеет некоторые недопустимые аргументы
Возможно, вы ввели «char *» вместо «char []» при публикации.
Возможно, это связано с нашим историческим пониманием литералов. До C # значение, заключенное в кавычки (например, «astringvalue»), можно было рассматривать как указатель на символ. Однако в C # «astringvalue» — это просто объект типа string class . Оператор:
String s= new String("Hello World");
подразумевало бы создание объекта типа String class и вызов его конструктора. Компилятор проверяет список конструкторов, доступных для класса string . Он не может найти ни одного конструктора, который мог бы принять объект string («Hello world»). Как и в любой другой ситуации, компилятор делает наилучшее предположение о том, какой метод является «ближайшим» из списка перегруженных методов — в этом случае предполагается, что строковое значение «Hello world» ближе всего к массиву символов (char []) — и сообщает вам, что ваш «Hello world» (переданное вами значение) является недопустимым значением для «char []».
Ответ №9:
На мой взгляд, основное различие заключается в «Передаче по ссылке» и «передаче по значению» в .NET и JAVA.
Что приводит к шаблону проектирования в Java по причине, которая может быть
Конструктор для копирования объекта того же класса.
В .NET вам не требуется, чтобы такой конструктор копировал / клонировал строку, потому что он может сделать это следующим образом (напрямую),
‘String test = txtName .Текст;’
Это мое понимание .net и java.
Надеюсь, я смог дать правильные рассуждения.
Спасибо и с уважением
Жесткая ошибка
Комментарии:
1. НЕТ, НЕТ, НЕТ. Вся передача (без
out
иref
) в C # является вызовом по значению (по ссылке) . Для ссылочных типов это лучше описать как совместное использование вызовов по объектам . Вызов по ссылке не связан, как и «Конструктор копирования». Неизменяемые объекты [обычно] не нуждаются в «Конструкторе копирования» — строки в Java и C # неизменяемы.2. C имеет очень точное определение конструктора копирования , которое используется даже для неизменяемых типов в C — но это C , а не C # или Java.
3. Сборка мусора — большая часть того, почему C должен создавать копии, когда C # и Java этого не делают. В C , даже если объект имеет неизменяемое содержимое , его может потребоваться клонировать, поскольку у копии другое время жизни. В системе GC можно просто бесконечно продлевать срок службы оригинала до тех пор, пока он все еще необходим.