2010-02-17 13 views
8

prendere questa classe come ad esempio:NHibernate eccezione: metodo Add dovrebbe essere 'pubblico/protetto virtuale' o 'protetti interno virtuale'

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

Quando si esegue l'applicazione senza la parola chiave virtuale di metodo Add, ho ottenere questo errore:

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

capisco perché le proprietà devono dichiarare come virtuale, perché thay bisogno di essere ignorato dalla funzione di lazy loading.

Ma non capisco perché i metodi devono essere dichiarati come virtuali ... devono essere sovrascritti per quale motivo?

Questo molto confuso!

risposta

10

Anche i metodi devono essere virtuali perché possono accedere ai campi. Prendi in considerazione questa situazione:

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) 
    // ... 
    } 
} 
4

Credo sia necessario per la funzione di caricamento lazy in NHibernate dove NHibernate crea proxy della tua entità e controlla tutti gli accessi ad esso. Questo è il motivo per cui ogni singolo metodo e proprietà deve essere virtuale. Fondamentalmente, se c'è un membro che fa qualcosa con l'entità, NH ha bisogno di saperlo e sfruttarlo. Come accennato in precedenza, per fare di NHibernate la "magia" crea classi proxy che ereditano dalle tue entità (Categoria nel tuo caso). Tuttavia, se le entità implementano un'interfaccia, utilizzerà tale interfaccia per creare un proxy anziché tipi concreti. In questo modo, non devi contrassegnare tutto virtuale.

MODIFICA: Alcune correzioni ... Secondo this, sono costretto a dire che sembra quasi che NH non faccia davvero nulla con i metodi virtuali, dopotutto. E ho persino letto qualcuno che mi ha detto di aver rimosso questo controllo run-time dall'assemblaggio del nucleo NH per aggirare il problema. La mia ipotesi sarebbe che si tratta di requisiti più vecchi che non sono stati rimossi. La cosa interessante è che sembra che ci sia un'iniziativa per utilizzare PostSharp per i proxy statici, quindi le tue classi non dovranno dichiarare nulla di virtuale affinché NH generi proxy. La cosa brutta è che sembra essere stato bloccato in un ramo per quasi due anni.

+1

Il richiedente stava chiedendo del razionale per aver richiesto che i metodi fossero specificamente virtuali. Ha spiegato che comprende già le classi proxy per il caricamento lento. –

Problemi correlati