#c# #c#-9.0
#c# #c #-9.0
Вопрос:
Можно ли использовать общедоступный метод инициализации и частный сеттер для одного и того же свойства?
В настоящее время я получаю ошибку CS1007 «Средство доступа к свойству уже определено».
public record Stuff
{
public int MyProperty { get; init; private set; } // Error
public void SetMyProperty(int value) => MyProperty = value;
}
var stuff = new Stuff
{
MyProperty = 3, // Using the init accessor
};
stuff.SetMyProperty(4); // Using the private setter (indirectly)
Моим лучшим предположением было бы использовать закрытую переменную-член, свойство для этой переменной с get
init
помощью средств доступа и (не реализуемых автоматически) и функции-члена setter . Можно ли это сделать проще?
Комментарии:
1. Какой в этом смысл? Вы пытаетесь дважды указать установщик.
init
это тоже сеттер2. Это невозможно, нет. Средство
init
доступа использует тот жеset_MyProperty
методset
set, что и средство доступа: оно просто украшено amodreq
.3. Вся идея
init
состоит в том, чтобы сделать свойство неизменяемым. Наличие установщика противоречит этой цели4. Цель состоит в том, чтобы иметь «в основном неизменяемые» объекты, где правило thumb является неизменяемым, но есть несколько четко определенных исключений. Мы можем использовать
with
, но это не делает возможной какую-либо логику (например, проверки согласованности).5. Я думаю, лучшим решением, которое я мог бы предложить для этого, было бы использовать частный сеттер и установить начальное значение через конструктор.
Ответ №1:
Аналогично указанию конструктора для инициализации вашего значения, вы можете использовать частное резервное поле, чтобы вы все еще могли воспользоваться преимуществами логики инициализации и разрешить инициализацию без определенного конструктора
public record Stuff
{
private int _myProperty;
public int MyProperty { get => _myProperty; init => _myProperty = value; }
public void SetMyProperty(int value) => _myProperty = value;
}
var stuff = new Stuff
{
MyProperty = 3 // Using the init accessor
};
stuff.SetMyProperty(4); // Using the private setter (indirectly)
Ответ №2:
Нет, вы не можете. Ключевое слово init было добавлено в попытке сделать неизменяемые свойства объектов.
Итак, если у вас есть запись:
public record Stuff
{
public int MyProperty { get; init; } // This can not be changed after initialization
}
MyProperty
может быть установлен только во время инициализации вашей записи.
Если вы хотите, чтобы ваше свойство было изменяемым, тогда вы используете средство set
доступа вместо init
.
public record Stuff
{
public int MyProperty { get; set; } // This can
}
Комментарии:
1. Спасибо, Хасан, я имел в виду set
Ответ №3:
В качестве ответа @Jerry’s вы не можете использовать оба средства установки. Это связано с изменчивостью записи / объекта.
Если вы также хотите иметь private set
ers и некоторую логику инициализации, я использую конструкторы:
public record Stuff
{
public Stuff(int myProperty)
{
MyProperty = myProperty;
}
public int MyProperty { get; private set; }
public void SetMyProperty(int value) => MyProperty = value;
}
var stuff = new Stuff(3);
stuff.SetMyProperty(4);
Все дело в требованиях к домену.
Stuff.MyProperty
Нужно ли публично изменять?- Если это так, каким будет значение этого свойства по умолчанию при инициализации экземпляра Stuff? Ожидает ли домен значение по умолчанию?
и т.д..