2015-02-09 5 views
1

Следующий код не может скомпилироваться с ошибкой Cannot implicitly convert type 'string' to 'String' в C#.Невозможно неявно преобразовать тип 'string' в 'String'

void Main() 
{ 
    Console.Write("Hello".Append("Mark")); 
} 

public static class Ext 
{ 
    public static String Append<String>(this String str, String app) 
    { 
     return str + " " + app; 
    } 
} 

Вы можете исправить ошибку компиляции, удалив параметр типа из метода расширения, но я задаюсь вопросом, почему это не может скомпилировать, учитывая, что typeof(string) == typeof(String) вычисляет true.

Следующая работает просто отлично:

void Main() 
{ 
    Console.Write("Hello".Append("Mark")); 
} 
public static class Ext 
{ 
    public static string Append<String>(this String str, string app) 
    { 
     return str + " " + app; 
    } 
} 
+2

Почему у вас ограничение типа '' здесь? –

+0

Я писал несколько методов расширения, которые использовали параметр T, но это только имело смысл для String, поэтому я заменил T на String и был удивлен, получив ошибку. Конечно, этого не должно быть. Следующий код компилируется и работает просто отлично: 'void Main() { Console.Write (« Hello ».Append (« Mark »)); } общественный статический класс Ext { общественности статической строки Append (это строка, ул строка приложение) { возвращение ул + "" + приложение; } } ' – MarkFl

+2

Нет необходимости создавать методы расширения, поскольку первый аргумент' this String str' уже определяет тип цели. – helb

ответ

8

Append<String> не тип, это имя параметра типа. Это то же самое, что и с использованием T, за исключением того, что вы назовете его String.

Очевидно, что это создает проблему, потому что теперь вы пытаетесь объединить общий тип с именем String в литературу string.

Вы можете просто пропустить это вообще:

public static String Append(this String str, String app) 
{ 
    return str + " " + app; 
} 

Причина ваш второй подход работает, потому что вы теперь использовать string, который удаляет двусмысленность параметра типа по имени String.

Это означает, что объединение состоит из универсального типа с именем String, который имеет фактический тип string, string буквальные и переменный типа string. Это может снова скомпилироваться, но это уродливо, и вы никогда не должны этого делать.

2

Проблема у вас есть, что вы используете общий аргумент типа String который understooed компилятором как «какой-то тип, но давайте назовем его String», а не фактического типа System.String.

Кроме того, нет необходимости генерировать методы расширения, поскольку первый аргумент this String str уже определяет целевой тип. Просто удалите параметр типа, и вы хорошо идти:

public static string Append(this string str, string app) 
{ 
    return str + " " + app; 
} 
-1

I'think это решит проблему с правильным методом расширения, а также использование string.Format()

class Program 
{ 
    static void Main() 
    { 
     Console.Write("Hello".Append("Mark")); 
    } 
} 

public static class Ext 
{ 
    public static System.String Append(this System.String str, System.String app) 
    { 
     return System.String.Format("{0} {1}", str,app); 
    } 
} 
0

компилятором видит ваше объявление:

public static string Append<String>(this String str, string app) 

И затем обрабатывает String в качестве параметра типа. Таким образом, str не является (обязательно) типа System.String. Это зависит от вашего параметра типа. Второй аргумент, а именно app, однако, имеет тип System.String, потому что вы использовали строчные буквы string. В организме у вас есть

return str + " " + app; 

Что значит «взять str и добавить его в строку " ", а затем в строке app», но компилятор не знает, как добавить str, потому что неизвестного типа String.

Было бы лучше, чтобы удалить параметр типа в целом, потому что вы не использовать его в любом случае, но если вы хотите, чтобы остаться, вы должны изменить свое название на T (это соглашение)

Смежные вопросы