С#: Как установить значение по умолчанию для свойства в частичном классе?
Я очень новичок в С#, поэтому, пожалуйста, несите меня...
Я реализую частичный класс и хотел бы добавить два свойства следующим образом:
public partial class SomeModel
{
public bool IsSomething { get; set; }
public List<string> SomeList { get; set; }
... Additional methods using the above data members ...
}
Я хотел бы инициализировать оба элемента данных: от IsSomething
до True
и SomeList
до new List<string>()
. Обычно я делал это в конструкторе, однако, поскольку это частичный класс, я не хочу касаться конструктора (должен ли я?).
Какой лучший способ достичь этого?
Спасибо
PS Я работаю в ASP.NET MVC, добавляя функциональность к определенной модели, отсюда и частичный класс.
Ответы
Ответ 1
Обновлено для С# 6
С# 6 добавила возможность назначать значение по умолчанию для авто-свойств. Значение может быть любым выражением (оно не обязательно должно быть константой). Вот несколько примеров:
// Initialize to a string literal
public string SomeProperty {get;set;} = "This is the default value";
// Initialize with a simple expression
public DateTime ConstructedAt {get;} = DateTime.Now;
// Initialize with a conditional expression
public bool IsFoo { get; } = SomeClass.SomeProperty ? true : false;
Оригинальный ответ
Автоматически реализованные свойства могут быть инициализированы в конструкторе класса, но не сами по себе.
public SomeModel
{
IsSomething = false;
SomeList = new List<string>();
}
... или вы можете использовать свойство с поддержкой поля (немного больше работы) и инициализировать само поле...
private bool _IsSomething = false;
public bool IsSomething
{
get { return _IsSomething; }
set { _IsSomething = value; }
}
Обновление: Мой вышеприведенный ответ не проясняет проблему этого в частичном классе. Ответ Mehrdad предлагает решение с использованием частичного метода, что соответствует моему первому предложению. Мое второе предложение об использовании неавтоматически реализованных свойств (вручную реализованных свойств?) Будет работать для этой ситуации.
Ответ 2
Первое свойство (IsSomething) является логическим. По умолчанию это будет false.
Второе свойство, так как оно является ссылочным типом, по умолчанию будет равно нулю без каких-либо усилий с вашей стороны. Вам не нужно прикасаться к конструктору, поскольку ссылочные типы (классы) автоматически начинаются с нуля в .NET.
Если вы хотите использовать значение, отличное от значения по умолчанию, у вас есть два варианта -
Сначала используйте поле хранилища:
private bool isSomething = true;
public bool IsSomething {
get { return this.isSomething; }
set { this.isSomething = value; }
}
Второй вариант - добавьте его в конструктор.
Обратите внимание, что первый вариант не имеет дополнительных накладных расходов - это в основном то, что делает компилятор при использовании автоматического свойства.
Ответ 3
У вас не может быть двух конструкторов в двух частях частичного класса. Однако вы можете использовать частичные методы, чтобы выполнить что-то вроде этого:
// file1:
partial void Initialize();
public Constructor() {
// ... stuff ... initialize part 1
Initialize();
}
// file2:
void Initalize() {
// ... further initializations part 2 might want to do
}
Если никакие части частичного класса не определяют частичный метод, все обращения к нему будут опущены.
Ответ 4
ПРЕДУПРЕЖДЕНИЕ для пользователей частичных классов WCF
Если вы пытаетесь добавить свойство в класс прокси-сервера WCF (сгенерированный с помощью Add Service Reference), вы можете быть удивлены, обнаружив, что частные поля не инициализируются, потому что, по-видимому, никакой конструктор вообще не называется.
Если вы попытаетесь сделать это (как предложено в некоторых других ответах), он никогда не будет вызван:
private bool _sendEmail = true;
Это не имеет никакого отношения к тому, находится ли поле в частичном классе или нет.
Что вам нужно сделать, это добавить атрибут [OnDeserialized], который позволит вам выполнить дальнейшую инициализацию объекта. Это часть System.Runtime.Serialization, поэтому полезно только в контексте сериализации при использовании DataContractSerializer.
public partial class EndOfDayPackageInfo
{
[OnDeserialized()]
public void Init(StreamingContext context)
{
_sendEmail = true;
}
private bool _sendEmail;
public bool SendEmail
{
get
{
return _sendEmail;
}
set
{
_sendEmail = value;
RaisePropertyChanged("SendEmail");
}
}
}
Другим подходом является "ленивая загрузка" свойства, но этот подход гораздо менее изящный.
private bool _sendEmail;
private bool _sendEmailInitialized;
public bool SendEmail
{
get
{
if (!_sendEmailInitialized)
{
_sendEmailInitialized = true;
_sendEmail = true; // default value
}
return _sendEmail;
}
set
{
if (!_sendEmailInitialized)
{
// prevent unwanted initialization if 'set' is called before 'get'
_sendEmailInitialized = true;
}
_sendEmail = value;
RaisePropertyChanged("SendEmail");
}
}
Ответ 5
Для этого не используйте автоматическое свойство, но старый способ
YourType _yourParameter = yourDefaultValue;
public YourType YourParameter
{
get{return _yourParameter;}
set{_yourParameter=value;}
}
Ответ 6
Для пользователя версии 6.0 С# можно инициализировать свойства следующим образом:
public bool IsSomething { get; set; } = true;
public List<string> SomeList { get; set; } = new List<string>();
Ответ 7
Оба свойства уже будут иметь требуемые значения по умолчанию.
Нет ничего плохого в том, что у конструктора есть частичный класс. Частичные классы никоим образом не являются особенными, кроме того, что их исходный код распространяется на несколько файлов/объявлений.
Ответ 8
private bool _InternalUserContactUpdate = false;
public bool InternalUserContactUpdate
{
get { return _InternalUserContactUpdate; }
set { _InternalUserContactUpdate = value; }
}
Затем, когда вы хотите переопределить значение при условии,
if(!objUserModel.FirstName.ToLower().Equals(entry.Key[0].Attributes.Contains("firstname").ToString().ToLower()))
{
objUserModel.InternalUserContactUpdate= true;
}
Надеюсь, это поможет