Исключение NHibernate: метод Добавляет, должна быть 'общественность/защищать, виртуальная' или 'защищенный внутренний виртуальный'

Посещайте этот урок как пример:

public class Category : PersistentObject<int>
{
    public virtual string Title { get; set; }
    public virtual string Alias { get; set; }

    public virtual Category ParentCategory { get; set; }
    public virtual ISet<Category> ChildCategories { get; set; }


    public /*virtual*/ void Add(Category child)
    {
        if (child != null)
        {
            child.ParentCategory = this;
            ChildCategories.Add(child);
        }
    }
}

Когда запуск приложения без виртуального ключевого слова добавляет метод, я получающий эту ошибку:

method Add should be 'public/protected virtual' or 'protected internal virtual'

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

Но я не понимаю, почему Методы должны быть, объявляют как виртуальный... они должны быть переопределены по какой причине?

Это очень сбивающее с толку!

9
задан Fitzchak Yitzchaki 17 February 2010 в 03:27
поделиться

2 ответа

Методы также должны быть виртуальными, поскольку они могут обращаться к полям. Рассмотрим эту ситуацию:

class Entity
{

  //...
  private int a;
  public virtual int A 
  { 
     get { return a; }
  }

  public virtual void Foo()
  {
    // lazy loading is implemented here by the proxy
    // to make the value of a available
    if (a > 7) 
    // ...
  }
}
10
ответ дан 4 December 2019 в 14:28
поделиться

Я считаю, что это требуется для функции отложенной загрузки в NHibernate, где NHibernate создает прокси-серверы вашего объекта и контролирует весь доступ к нему. Вот почему каждый метод и свойство должны быть виртуальными. По сути, если есть член, который что-то делает с сущностью, NH необходимо знать об этом и подключаться к нему. Как упоминалось ранее, для того, чтобы NHibernate совершал «магию», он создает прокси-классы, наследуемые от ваши сущности (Категория в вашем случае). Однако, если вы заставляете свои сущности реализовывать интерфейс, они будут использовать этот интерфейс для создания прокси вместо конкретных типов. Таким образом, вам не нужно будет отмечать все как виртуальное.

РЕДАКТИРОВАТЬ: Некоторые исправления ... Согласно this , я вынужден сказать, что похоже, что NH на самом деле ничего не делает с виртуальными методами, в конце концов. И я даже читал, что кто-то сказал, что они удалили эту проверку времени выполнения из сборки ядра NH, чтобы обойти это. Я предполагаю, что это более старые требования, которые не были удалены. Замечательно то, что похоже, что существует инициатива по использованию PostSharp для статических прокси, поэтому вашим классам не нужно будет объявлять что-либо виртуальное, чтобы NH могла сгенерировать прокси. Плохо то, что похоже, что он застрял в ветке почти два года.

4
ответ дан 4 December 2019 в 14:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: