2010-02-17 11 views
8

tomar esta clase como ejemplo:NHibernate excepción: método Add debe ser 'público/virtuales protegidos' o 'interna protegida virtual'

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

Cuando se ejecuta la aplicación sin la palabra clave virtual del método add, yo conseguir este de error:

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

entiendo por qué propiedades tienen que declarar como virtual, porque parecían necesita ser modificado mediante la función de carga diferida.

Pero no entiendo por qué los métodos deben declararse como virtuales ... deben ser anulados por qué razón?

Esto muy confuso!

Respuesta

10

Los métodos también deben ser virtuales porque pueden acceder a los campos. Considere esta situación:

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

Creo que esto es necesario para la función de carga diferida en NHibernate, donde NHibernate crea proxies de su entidad y controla todo el acceso a ella. Esta es la razón por la cual cada método y propiedad debe ser virtual. Básicamente, si hay un miembro haciendo algo con la entidad, NH necesita saberlo y aprovecharlo. Como se mencionó anteriormente, para que NHibernate haga la 'magia' crea clases de proxy que heredan de sus entidades (Categoría en su caso). Sin embargo, si hace que sus entidades implementen una interfaz, usará esa interfaz para crear un proxy en lugar de tipos concretos. De esta forma, no debería marcar todo lo virtual.

EDITAR: Algunas correcciones ... Según this, me siento obligado a decir que casi parece que NH realmente no hace nada con los métodos virtuales, después de todo. Incluso leí a alguien diciendo que eliminaron este cheque en tiempo de ejecución del ensamblaje central de NH solo para evitarlo. Mi suposición sería que se trata de requisitos más antiguos que no se han eliminado. Lo bueno es que parece que hay una iniciativa para usar PostSharp para proxies estáticos, por lo que sus clases no tendrán que declarar nada virtual para que NH genere proxies. Lo malo es que parece que ha estado atrapado en una sucursal durante casi dos años.

+1

El asker preguntaba acerca de la racionalidad para requerir que los métodos sean específicamente virtuales. Explicó que ya entiende las clases proxy para la carga lenta. –

Cuestiones relacionadas