#c# #interface #extension-methods
#c# #интерфейс #методы расширения
Вопрос:
Данный интерфейс
public interface IHaveError
{
string ErrorMessage { get; set; }
}
Расширение
public static class HaveErrorExtensions
{
public static void SetErrorMessage(this IHaveError target, string message)
{
target.ErrorMessage = message;
}
}
Класс
public class HaveError : IHaveError
{
public string ErrorMessage { get; set; }
public void DoSomething()
{
this.SetErrorMessage(message);
}
}
Почему this.
требуется при вызове метода расширения? Имя не разрешается без него.
Ответ №1:
Вот как методы расширения работают в спецификации языка C #. Если вы прочитали раздел «7.6.5.2 Вызовы метода расширения», в нем в основном говорится, что у вас должен быть вызов метода одной из следующих форм:
expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )
Если вы заметили, expr
это требуется для поиска метода расширения, чтобы быть опцией.
В этом случае он this.
становится expr.
указанным выше, так что вышеуказанное может быть преобразовано в вызов статического метода для типа, где это метод расширения, определенный как:
C . indentifier ( expr , args )
В вашем случае, для того, чтобы компилятор «нашел» (или даже искал) вызов метода, вам необходимо указать некоторый тип «expr». Уточняет явный this.
. Это заставляет компилятор принимать это:
this.SetErrorMessage(message);
И найдите соответствующий метод расширения, который работает с типом, переводя его в:
HaveErrorExtensions.SetErrorMessage(this, message);
Ответ №2:
Методы расширения — это просто статические методы с некоторым синтаксическим сахаром (очень вкусный синтаксический сахар!), применяемый компилятором. Ссылка на объект, по которой вызывается метод, на самом деле является первым аргументом метода.
Компилятор должен знать, какой экземпляр вы имеете в виду. Он не может угадать.
Ответ №3:
Потому что this
ссылается на текущий объект, с которым вы работаете. Без this
компилятор не знает, к чему применять метод расширения.