2010-02-17 6 views
8

Nehmen Sie diese Klasse als Beispiel:NHibernate Ausnahme: Methode Add sollte ‚public/geschützte virtuelle‘ oder ‚virtuelle internen geschützt‘

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

Wenn die Anwendung ohne das Schlüsselwort virtual von Add-Methode ausgeführt wird, ich das immer Fehler:

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

ich verstehe, warum Eigenschaften als virtuelle erklären müssen, weil thay durch die träges Laden-Funktion außer Kraft gesetzt werden müssen.

Aber ich verstehe nicht, warum Methoden als virtuell deklariert werden müssen ... sie müssen aus welchem ​​Grund überschrieben werden?

Das ist sehr verwirrend!

Antwort

10

Auch Methoden müssen virtuell sein, da sie auf Felder zugreifen können. Stellen Sie sich diese Situation vor:

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

Ich glaube, dass dies für die Lazy-Loading-Funktion in NHibernate erforderlich ist, wo NHibernate Proxies Ihrer Entität erstellt und den Zugriff darauf steuert. Aus diesem Grund muss jede einzelne Methode und Eigenschaft virtuell sein. Wenn es ein Mitglied gibt, das irgendetwas mit der Entität macht, muss NH davon wissen und es anzapfen. Wie bereits erwähnt, erstellt NHibernate die Magie, um Proxy-Klassen zu erstellen, die von Ihren Entitäten (Kategorie in Ihrem Fall) erben. Wenn Sie jedoch Ihre Entitäten dazu veranlassen, eine Schnittstelle zu implementieren, wird diese Schnittstelle verwendet, um einen Proxy anstelle von konkreten Typen zu erstellen. Auf diese Weise müssten Sie nicht alles virtuell markieren.

EDIT: Einige Korrekturen ... Nach this, ich bin gezwungen zu sagen, dass es fast aussieht wie NH nicht wirklich etwas mit virtuellen Methoden, immerhin. Und ich las sogar jemanden, der sagte, dass diese Laufzeitprüfung von der NH-Kernbaugruppe entfernt wurde, nur um es zu umgehen. Meine Annahme wäre, dass es sich um ältere Anforderungen handelt, die nicht entfernt wurden. Die coole Sache ist, dass es aussieht, als gäbe es eine Initiative, PostSharp für statische Proxies zu verwenden, also müssen Ihre Klassen nichts virtuell deklarieren, damit NH Proxies generiert. Das Schlimme ist, dass es aussieht, als wäre es seit fast zwei Jahren in einem Zweig festgefahren.

+1

Der Fragesteller fragte nach dem Grund für die Notwendigkeit von Methoden speziell virtuell zu sein. Er erklärte, dass er die Proxy-Klassen für Lazy-Loading bereits versteht. –

Verwandte Themen