MSDN docs содержит раздел о неявных преобразованиях:
var s = $"hello, {name}";
System.IFormattable s = $"Hello, {name}";
System.FormattableString s = $"Hello, {name}";
Из первой строки следует, что исходный тип интерполированной строки string
. Хорошо, я могу это понять, но потом... Я понимаю, что строка не реализует IFormattable
. Таким образом, похоже, что какая-то магия из компилятора похожа на то, что она делает с lambdas.
Теперь угадайте вывод этого кода:
void Main()
{
PrintMe("Hello World");
PrintMe($"{ "Hello World"}");
}
void PrintMe(object message)
{
Console.WriteLine("I am a " + message.GetType().FullName);
}
//void PrintMe(string message)
//{
// Console.WriteLine("I am a string " + message.GetType().FullName);
//}
void PrintMe(IFormattable message)
{
Console.WriteLine("I am a " + message.GetType().FullName);
}
Подсказка:
Я System.String
Я System.Runtime.CompilerServices.FormattableStringFactory + ConcreteFormattableString
Если вы удалите комментарии из второго метода, вы получите:
Я - строка System.String
Я - строка System.String
Ok
Может быть, я не очень хорошо понимаю перегрузку разрешения, но 14.4.2 из С# spec подразумевает, что тип переданного параметра определяется первым, но снова как делаются работы лямбда?
void Main()
{
PrintMe(() => {});
PrintMe(() => {});
}
void PrintMe(object doIt)
{
Console.WriteLine("I am an object");
}
//void PrintMe(Expression<Action> doIt)
//{
// Console.WriteLine("I am an Expression");
//}
void PrintMe(Action doIt)
{
Console.WriteLine("I am a Delegate");
}
Удалить комментарии и...
CS0121 Вызов неоднозначен между следующими способами или свойства: 'UserQuery.PrintMe(выражение)' и 'UserQuery.PrintMe(Действие)
Поэтому я не понимаю поведение компилятора.
Update:
Чтобы усугубить ситуацию, я проверил это поведение для методов расширения:
void Main()
{
PrintMe("Hello World");
PrintMe($"{"Hello World"}");
"Hello World".PrintMe();
$"{"Hello World"}".PrintMe();
}
void PrintMe(object message)
{
Console.WriteLine("I am a " + message.GetType().FullName);
}
void PrintMe(IFormattable message)
{
Console.WriteLine("I am a " + message.GetType().FullName);
}
public static class Extensions
{
public static void PrintMe(this object message)
{
Console.WriteLine("I am a " + message.GetType().FullName);
}
public static void PrintMe(this IFormattable message)
{
Console.WriteLine("I am a " + message.GetType().FullName);
}
}
Теперь у меня это так:
Я - System.String
Я - System.Runtime.CompilerServices.FormattableStringFactory + ConcreteFormattableString
Я - System.String
Я - System.String