MarkFl
MarkFl

Reputation: 368

Cannot implicitly convert type 'string' to 'String'

The following code fails to compile with the error Cannot implicitly convert type 'string' to 'String' in C#.

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

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

You can fix the compile error by removing the Type parameter from the extension method but I'm wondering why this fails to compile given that typeof(string) == typeof(String) evaluates to true.

The following also works just fine:

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

Upvotes: 1

Views: 1748

Answers (4)

joozek
joozek

Reputation: 2191

The compiler sees your declaration:

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

And it then treats String as type parameter. So str is not (necessarily) of type System.String. It's of whatever your type parameter turns out to be. Second argument, namely app however is of type System.String, because you used lowercase string. In the body you have

return str + " " + app;

Which means "take str and add it to string " " and then to string app", but the compiler doesn't know how to add str, because it's of unknown type String.

It would be best to remove the type parameter altogether, because you don't use it anyway, but if you want it to stay you should change its name to T (that's the convention)

Upvotes: 0

Stofa
Stofa

Reputation: 25

I'think this solves your Problem with an correct extension method and also the usage of 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);
    }
}

Upvotes: -1

helb
helb

Reputation: 7773

The problem you have is, that you use a generic type argument String which is understooed by the compiler as "some type, but let us call it String" and not as the actual type System.String.

Furthermore, there is no need to make extension methods generic since the first argument this String str already defines the target type. Just remove the type parameter and you are good to go:

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

Upvotes: 2

Jeroen Vannevel
Jeroen Vannevel

Reputation: 44439

The Append<String> is not a type, it's the name of a type parameter. It's the same as using T except now you name it String.

Obviously this gives a problem because now you try to concatenate a generic type with name String to a string literal.

You can just omit this altogether:

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

The reason your second approach works is because you now use string which removes the ambiguity of the type parameter named String.

This means that your concatenation consists of the generic type named String which has the actual type string, a string literal and a variable of type string. This can compile again but it's ugly and you should never do it.

Upvotes: 8

Related Questions