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

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

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

public partial class SomeModel
{
    public bool IsSomething { get; set; }
    public List<string> SomeList { get; set; }

    ... Additional methods using the above data members ...
}

Я хотел бы инициализировать оба члена данных:IsSomething to True и SomeList to new List<string>(). Обычно я бы сделал это в конструкторе, однако, поскольку это частичный класс, я не хочу прикасаться к конструктору (должен ли я?).

чего самый лучший путь достигнуть это?

спасибо

PS Я работаю в ASP.NET MVC, добавляя функциональность к определенной модели, следовательно, частичный класс.

8 ответов


обновлено для C# 6

C# 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; }
}

обновление: мой ответ выше не проясняет проблему этого нахождения в частичном классе. ответ Мехрдада предлагает решение с использованием частичного метода, который соответствует моему первому предложению. Мое второе предложение использовать неавтоматически реализованные свойства (вручную реализованные свойства?) будет работать для этой ситуации.


первое свойство (IsSomething) является логическим. По умолчанию он будет false.

второе свойство, так как это ссылочный тип, по умолчанию будет null без каких-либо усилий с вашей стороны. Вам не нужно прикасаться к конструктору, так как ссылочные типы (классы) будут автоматически запускаться как null .Сеть.

Если вы хотите использовать значение не по умолчанию, у вас будет два варианта -

во-первых, используйте поле резервного хранения:

private bool isSomething = true;
public bool IsSomething {
    get { return this.isSomething; }
    set { this.isSomething = value; }
}

второй вариант - добавить его в конструктор.

обратите внимание, что первый вариант не имеет дополнительных накладных расходов - это в основном то, что компилятор делает при использовании автоматического свойства.


вы не можете иметь два конструктора в двух частях разделяемого класса. Однако, вы можете использовать частичное методов чтобы сделать что-то подобное:

// file1:
partial void Initialize();
public Constructor() {
    // ... stuff ... initialize part 1
    Initialize();
}

// file2:
void Initalize() {
    // ... further initializations part 2 might want to do
}

Если никакие части частичного класса не определяют частичный метод, все вызовы к нему будут опущены.


предупреждение для пользователей частичных классов WCF

Если вы пытаетесь добавить свойство в прокси-класс WCF (генерируемый ссылкой на службу Add), вы можете быть удивлены, обнаружив, что частные поля не инициализируются, потому что, по-видимому,конструктор вообще не называется.

Если вы попытаетесь сделать это (как это предлагается в других ответах), он никогда не будут называться :

    private bool _sendEmail = true;

Это не имеет ничего общего с Ли поле находится в частичном классе или нет.

что вам нужно сделать, это добавить [OnDeserialized] атрибут, который позволяет выполнять дальнейшую инициализацию объекта. Это часть системы.Во время выполнения.Сериализация so полезна только в контексте сериализации при использовании 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");
        }
    }

для этого не используйте автоматическое свойство, а старый способ

YourType _yourParameter = yourDefaultValue;
public YourType YourParameter
{
   get{return _yourParameter;}
   set{_yourParameter=value;}
}

для пользователя версии 6.0 C# можно инициализировать свойства следующим образом:

public bool IsSomething { get; set; } = true;
public List<string> SomeList { get; set; } = new List<string>();

оба ваших свойства уже будут иметь требуемые значения по умолчанию.

нет ничего плохого в том, чтобы иметь конструктор в частичном классе. Частичные классы никоим образом не являются особыми, кроме того, что их исходный код распространяется по нескольким файлам/объявлениям.


 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;
        }

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