GeekBrains вопросы - Входное тестирование. ReferenceEquals С#
Ребята, проходил тестирования входное от GeekBrains. Это для бесплатных курсов по программированию. Я честно сказать обалдел от сложности вопросов. Вот один из них, может кому полезно будет. Я программист C# и то не сразу догадался, какой правильный ответ.
Какой результат сравнения будет выведен на экран в указанных трёх строках?
public class Text
{
public string Value1 { get; } = new string("Hello");
public string Value2 => new string("Hello");
public string Value3 => "Hello";
}
class Program
{
static void Main(string[] args)
{
Text text = new Text();
Console.WriteLine(ReferenceEquals(text.Value1, text.Value1));
Console.WriteLine(ReferenceEquals(text.Value2, text.Value2));
Console.WriteLine(ReferenceEquals(text.Value3, text.Value3));
}
}
Да и код работает на языке C# 8.0 и выше, .netCore 3.1
Ответ True,False,True
Дело в том, что Object.ReferenceEquals(Object, Object) вернет значение true, если параметр objA соответствует тому же экземпляру, что и параметр objB, или же оба они являются равны NULL; в противном случае — значение false.
В строке
public string Value2 => new string("Hello");
создается новый экземпляр. Потому и false.
Объясните пожалуйста, что это за конструкция такая с лямбда выражением? Я впервые такое вижу. Зачем вообще нужна такая конструкция и когда ее используют? Получается всегда, когда мы обращаемся к полю класса, вызывается лямбда выражение и вычисляется значение. Бессмыслица какая-то.
Ответы (1 шт):
=> (стрелочная функция, лямбда выражение) - это по факту синтаксический сахар (упрошение) для удобства разработчика, в вашем случае, который равен:
public class Text
{
[CompilerGenerated]
private readonly string <Value1>k__BackingField = new string("Hello");
public string Value1
{
[CompilerGenerated]
get
{
return <Value1>k__BackingField;
}
}
public string Value2
{
get
{
return new string("Hello");
}
}
public string Value3
{
get
{
return "Hello";
}
}
}
Отсюда и true, false, true результат, т.к.:
- в первом случает, у вас один и тотже объект (сравнивается абсолютна одна и таже переменная), поэтому и true
- во втором случае, код создает каждый раз новую строку, сколько раз будет вызвано раз свойство
Value2стольно и будет разных объектов, получается при вызовеReferenceEquals(text.Value2, text.Value2)будет создано 2 объекта - в третьем случае будет true из-за интернирования строк, при компиляцие C#, все строки (константные строки, литералы) будут автоматичски обработаны так, что будут ссылать на один объект, т.к. строки не изменяемые, то нет смысла каждый раз создавать новый объект.