2010-11-03 3 views
1

Я реализую иерархию типов, используя наследование таблицы классов. Однако у меня возникают проблемы со статическими методами, возвращающими базовый тип вместо дочернего типа. Я нашел способ обойти это, но это не слишком красиво. Возьмем следующие классыВызов FindAll на производных классах с использованием наследования таблицы классов Castle ActiveRecord

public class Entity : ActiveRecordBase<Entity> { } 
public class Person : Entity {} 

вызова

Person.FindAll(); 

фактически возвращает Entity [] вместо Person []. Я могу обойти это, реализуя FindAll во всех производных классах, но кто хочет это сделать? Я также был в состоянии создать базовый класс, что все классы наследуют от реализации и

public R[] FindAll<R>() {} 

, но я просто не нравится внешний вид

Person.FindAll<Person>() 

Есть ли способ, чтобы быть в состоянии назвать FindAll() из производных классов и фактически получить производные классы вместо базового класса?

ответ

4

Вот как работает .net: для статических методов не существует полиморфизма. Вы уже нашли пару обходных решений, другое - , а не, чтобы полагаться на эти статические методы, унаследованные от ActiveRecordBase<T>, но вместо этого используйте ActiveRecordMediator<T>.

0

Может быть, вы могли бы сделать:

public class Entity<T> : ActiveRecordBase<T> { } 
public class Person : Entity<Person> {} 

Таким образом FindAll() вернется Person[]

+0

Проблема с этим вы не можете отобразить '' Entity , как это открытый общий класс. –

+0

Я использовал этот шаблон раньше, когда Entity должен использоваться для хранения некоторых общих значений (ex: id) и методов и как общего предка для всех объектов. Я не понимаю, почему вы хотите отобразить его. – gcores

+0

@gcores: поэтому вы можете поместить свойства Entity в отдельный класс. –

0

Даже в документации Castle.ActiveRecord использует обходной путь, который вы нашли.

Смотрите здесь для полного примера и некоторых других решений: http://docs.castleproject.org/Default.aspx?Page=Type%20hierarchy&NS=Active%20Record

Я скопировал код в случае исчезает этот сайт.

Базовый класс "сущность"

using Castle.ActiveRecord; 

[ActiveRecord("entity"), JoinedBase] 
public class Entity : ActiveRecordBase 
{ 
    private int id; 
    private string name; 
    private string type; 

    public Entity() 
    { 
    } 

    [PrimaryKey] 
    private int Id 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    [Property] 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    [Property] 
    public string Type 
    { 
     get { return type; } 
     set { type = value; } 
    } 

    public static void DeleteAll() 
    { 
     DeleteAll(typeof(Entity)); 
    } 

    public static Entity[] FindAll() 
    { 
     return (Entity[]) FindAll(typeof(Entity)); 
    } 

    public static Entity Find(int id) 
    { 
     return (Entity) FindByPrimaryKey(typeof(Entity), id); 
    } 
} 

Производные классы "Человек" и "Компания"

using Castle.ActiveRecord; 

[ActiveRecord("entitycompany")] 
public class CompanyEntity : Entity 
{ 
    private byte company_type; 
    private int comp_id; 

    [JoinedKey("comp_id")] 
    public int CompId 
    { 
     get { return comp_id; } 
     set { comp_id = value; } 
    } 

    [Property("company_type")] 
    public byte CompanyType 
    { 
     get { return company_type; } 
     set { company_type = value; } 
    } 

    public new static void DeleteAll() 
    { 
     DeleteAll(typeof(CompanyEntity)); 
    } 

    public new static CompanyEntity[] FindAll() 
    { 
     return (CompanyEntity[]) FindAll(typeof(CompanyEntity)); 
    } 

    public new static CompanyEntity Find(int id) 
    { 
     return (CompanyEntity) FindByPrimaryKey(typeof(CompanyEntity), id); 
    } 
} 

[ActiveRecord("entityperson")] 
public class PersonEntity : Entity 
{ 
    private int person_id; 

    [JoinedKey] 
    public int Person_Id 
    { 
     get { return person_id; } 
     set { person_id = value; } 
    } 

    public new static void DeleteAll() 
    { 
     DeleteAll(typeof(PersonEntity)); 
    } 

    public new static PersonEntity[] FindAll() 
    { 
     return (PersonEntity[]) FindAll(typeof(PersonEntity)); 
    } 

    public new static PersonEntity Find(int id) 
    { 
     return (PersonEntity) FindByPrimaryKey(typeof(PersonEntity), id); 
    } 
}