Почему компилятор требует для этого сложного синтаксиса? - PullRequest
1 голос
/ 01 апреля 2009

Или, «я делаю это неправильно»?

Я пишу небольшую функцию, которая при необходимости возвращает строку, заключенную в кавычки (как в кавычках), в противном случае она возвращает ее как есть. Символ вводится в функцию; результат - строка.

Сначала я попытался сделать:

private string QuotedChar(char ch) {
    if(ch < (char)128 && !char.IsWhiteSpace(ch))
        return(new string(ch));

    // ...
}

Однако компилятор говорит CS0214: «Указатели и буферы фиксированного размера могут использоваться только в небезопасном контексте» при компиляции этого оператора возврата. Если я изменю код, чтобы сказать вместо:

private string QuotedChar(char ch) {
    if(ch < (char)128 && !char.IsWhiteSpace(ch))
        return(new string(new char[] { ch }));

    // ...
}

... это работает просто отлично. Однако это кажется довольно бессмысленным. Я не понимаю, почему он думает, что я пытаюсь использовать указатель или буфер фиксированного размера, так как это просто символ. Я что-то упускаю серьезно глупо, или это проблема / ошибка?

К вашему сведению, это Mono 2.0, а не Microsoft .NET Framework. Я не запускаю Windows, поэтому у меня нет компилятора Microsoft C #, чтобы увидеть, делает ли он то же самое или нет, поэтому мне интересно, если это ошибка.

Ответы [ 5 ]

7 голосов
/ 01 апреля 2009

Ну, это не ошибка, которая не компилируется. Там нет перегрузки строкового конструктора, который принимает символ. Я подозреваю, что Моно подумал, что вы имели в виду конструктор string(char*), и попытался - что привело к ошибке.

Самый простой способ преобразования char в string - это просто вызвать ToString(), хотя:

private string QuotedChar(char ch) {
    if(ch < (char)128 && !char.IsWhiteSpace(ch))
        return ch.ToString()

    // ... 
}

Компилятор MS C # угадывает ту же перегрузку, но выдает другое сообщение об ошибке:

Test.cs (8,20): ошибка CS1502: лучшая перегруженный метод соответствует 'string.String(char*)' имеет некоторые неверные аргументы
Test.cs (8,31): ошибка CS1503: Аргумент '1': невозможно преобразовать из 'char' в 'char*'

2 голосов
/ 01 апреля 2009

Тот же код, скомпилированный в .NET, выдаст сообщение об ошибке, что не было перегрузки для строкового конструктора, который принимает символ в качестве параметра. Наиболее близким совпадением является указатель на символ, поэтому может быть причиной появления этого сообщения об ошибке в Mono.

Вы можете использовать перегрузку, которая принимает символ и счет:

return new String(ch, 1);

Или вы можете использовать метод ToString:

return ch.ToString();

Или статический метод ToString:

return Char.ToString(ch);
1 голос
/ 01 апреля 2009

System.String не имеет конструктора, который принимает один символ.

Есть две возможности:

String(Char*)

или

String(Char[])

Вот почему ваш второй вариант работает, а первый думает, что вы пытаетесь передать указатель (небезопасно).

0 голосов
/ 01 апреля 2009

Я бы изменил "return new string (ch)" на "return ch.ToString ()" Строка не имеет конструктора, который принимает один символ. У него, однако, есть тот, который берет char и count.

Вы могли бы пойти "новая строка (ch, 1)", чтобы создать строку, содержащую 1 символ, который будет тем, что находится в переменной ch.

0 голосов
/ 01 апреля 2009

Нет перегрузки для new string(), который принимает один символ. На самом деле вы получаете перегрузку, которая принимает символ *, что означает, что он ожидает указатель на массив символов с нулем в конце, но указатели разрешены только в небезопасном контексте.

Вместо создания массива вы могли бы сделать new string(ch, 1)

...