Можно ли вызывать виртуальные свойства из конструктора объекта NHibernate? - PullRequest
19 голосов
/ 21 января 2009

взгляните на этот пример кода:

public class Comment
{
    private Comment()
    { }

    public Comment(string text, DateTime creationDate, string authorEmail)
    {
        Text = text;
        CreationDate = creationDate;
        AuthorEmail = authorEmail;
    }

    public virtual string Text { get; private set; }
    public virtual DateTime CreationDate { get; set; }
    public virtual string AuthorEmail { get; private set; }
}

Я знаю, что вызывать виртуальные функции-члены из конструктора считается плохой практикой, однако в NHibernate мне нужно, чтобы свойства были виртуальными для поддержки отложенной загрузки. Считается ли это нормально в этом случае?

Ответы [ 6 ]

5 голосов
/ 21 января 2009

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

2 голосов
/ 22 января 2009

Чтобы расширить ответ Пако:

В большинстве случаев это не больно. Но если класс наследуется, virtual позволяет переопределять свойства get / set, поэтому поведение больше не полностью инкапсулировано и не контролируется, поэтому теоретически оно может нарушаться. FxCop предупреждает об этом, потому что это потенциальная проблема.

Цель FxCop - помочь вам предупредить вас о возможных проблемах. Не является неправильным использование свойств в конструкторе, если вы знаете, кто / что когда-либо наследует от класса, но это официально не является «наилучшей практикой».

Итак, ответ в том, что это нормально, если вы контролируете любое наследование класса. В противном случае, не используйте его и установите значения полей напрямую. (Это означает, что вы не можете использовать C # 3.0 для автоматического получения / установки свойств - вам придется писать свойства, оборачивая поля самостоятельно.)

Примечание: лично все мои проекты являются веб-сайтами, которые мы размещаем для клиентов. Таким образом, если предположить, что эта настройка остается неизменной для проекта, то стоит компромисса с необходимостью дублировать различные проверки на нуль / аргументы. Но в любом другом случае, когда я не уверен, что мы сохраним полный контроль над проектом и использованием класса, я бы не стал использовать этот ярлык.

1 голос
/ 04 февраля 2016

ИМХО, наилучшей практикой является использование свойств с полями поддержки:

public class Comment
{
    private DateTime _creationDate;
    private string _text;
    private string _authorEmail;
    private Comment() { }
    public Comment(string text, DateTime creationDate, string authorEmail)
    {
        _text = text;
        _creationDate = creationDate;
        _authorEmail = authorEmail;
    }
    public virtual string Text
    {
        get { return _text; }
        private set { _text = value; }
    }
    public virtual string AuthorEmail
    {
        get { return _authorEmail; }
        private set { _authorEmail = value; }
    }
    public virtual DateTime CreationDate
    {
        get { return _creationDate; }
        set { _creationDate = value; }
    }
}

Таким образом, вы можете избежать проблем на дочерних классах и больше не видеть предупреждений

1 голос
/ 21 января 2009

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

0 голосов
/ 21 января 2009

Я думаю, вы не должны вызывать это в конструкторе. Вы можете предоставить метод Initialize (), который можно вызвать после создания объекта.

В Initialize () вы можете вызывать необходимые виртуальные методы

0 голосов
/ 21 января 2009

Я знаю, что FxCop жалуется, если вы вызываете виртуальный метод в своем конструкторе, но я не знаю, что FxCop говорит, вызываете ли вы виртуальное свойство в своем конструкторе ...
Я бы подумал, что FxCop тоже будет жаловаться, поскольку свойство транслируется в метод в IL.

Вы также можете создавать свои свойства как «не виртуальные», и просто указать «lazy = false» в своем «сопоставлении классов» в NHIbernate. Это не повлияет на поведение отложенной загрузки коллекций.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...