Подтвердить что ты не робот

С#: Как установить значение по умолчанию для свойства в частичном классе?

Я очень новичок в С#, поэтому, пожалуйста, несите меня...

Я реализую частичный класс и хотел бы добавить два свойства следующим образом:

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, добавляя функциональность к определенной модели, отсюда и частичный класс.

4b9b3361

Ответ 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;
        }

Надеюсь, это поможет