Reputation: 368
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
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
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
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
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