Ваше действие назначает конфигурацию лямбда-параметра, который не имеет никакого эффекта, так как параметр является входным значением, он не возвращается из лямбда-выражения.Объекты передаются по ссылке, но ссылки копируются в параметры в вызовах функций, т. Е. conf
получит копию ссылки на carConfiguration
при вызове действия, подобного этому configureCar(carConfiguration);
Назначение и перезаписьэта локальная копия ссылки не имеет смысла.Вы должны использовать ключевое слово ref
, чтобы по существу передать ссылку на ссылку (переменную) на объект.При назначении переменной, помеченной ref
, она будет перезаписывать ссылку, хранящуюся в исходной переменной-члене, а не локальную переменную внутри лямбды.Это уже продемонстрировано в другом ответе.
Правильный метод для реализации того, что вы пытаетесь выполнить, - это не передавать ссылки, а настраивать объект внутри действия.Если вы хотите использовать существующую конфигурацию, просто передайте объект, как вы уже сделали.Нет необходимости писать действие, которое явно принимает ссылку на объект.
public Car(Action<CarConfiguration> configureCar)
{
carConfiguration = new CarConfiguration();
configureCar(carConfiguration);
}
// This is the common configuration pattern seen in .NET
Car myOwnCar = new Car(conf =>
{
conf.CarName = "Ferrari";
conf.CarModel = "LaFerrari"
/** etc **/
});
Если вы хотите скопировать значения из существующей конфигурации, вы можете написать метод для этого
public static class CarConfigurationExtensions
{
public static void CopyTo(CarConfiguration this source, CarConfiguration dest){
dest.CarName = source.CarName;
dest.CarModel = source.CarModel;
// etc
}
}
Car myOwnCar = new Car(conf => carConfiguration.CopyTo(conf));
Но ни при каких обстоятельствах не пишется действие, которое принимает ref
к локальной переменной вещь.Другой альтернативой является использование Func<CarConfiguration>
, например, так, может быть, если вы хотите выполнить отложенную инициализацию.
public Car(Func<CarConfiguration> configurator)
{
_configurator = configurator;
}
private Func<CarConfiguration> _configurator;
private CarConfiguration _carConfiguration;
public CarConfiguration CarConfiguration =>
_carConfiguration ?? (_carConfiguration = _configurator());
Car myOwnCar = new Car(() => carConfiguration);
Обратите внимание, как создается и сохраняется конфигурация - при первом обращении к ней, возможно, единственнойвремя принятия функции в конструкторе полезно.