Это будет намного проще, даже если вам придется делать это снова и снова.В отличие от использования отражения, вы не получите ошибку времени выполнения, если класс и интерфейс больше не совпадают по совпадению.Он просто не будет компилироваться.
public class PersonWrapper : INameable
{
private readonly Person _person;
public PersonWrapper(Person person)
{
_person = person ?? throw new ArgumentNullException(nameof(person));
}
public string Name => _person.Name;
public string Surname => _person.Surname;
}
Если вы сделаете что-то «общее» с отражением, это скомпилирует:
var list = new List<string>();
INameable person = ExtractInterface<INameable>(list);
Если у нас нет абсолютно никакого выбора, ничего, что «обманывает»«компилятор, чтобы мы могли компилировать вещи, которые не должны компилироваться, - это рецепт неприятностей.Он забирает один из самых мощных инструментов, которые мы можем использовать для предотвращения ошибок во время выполнения.
По сути, это тот же подход, который используется для "адаптации" HttpContext
к HttpContextBase
, HttpRequest
к * 1013.* и т. д., за исключением того, что это абстрактные классы вместо интерфейсов.
Первоначальные реализации не реализовывали интерфейс и не наследовали от абстрактного класса, но позже стало очевидно, что было бы полезно, если бы были абстракции (использующие термин свободно) для этих классов.
Таким образом, они создали новые абстрактные классы с точно такими же свойствами, как и у исходных классов, так же, как вы создали новые интерфейсы для некоторых существующих классов.
Они не использовали отражение, чтобы отобразить существующие классы в абстрактные классы.Они просто использовали упаковщик , который ведет себя так же, как и код выше.