Вызов 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() из производных классов и фактически получать производные классы вместо базового класса?
3 ответа
Вот как работает.net: нет полиморфизма для статических методов. Вы уже нашли пару обходных путей, другой - не полагаться на эти статические методы, унаследованные от ActiveRecordBase<T>
, но вместо этого использовать ActiveRecordMediator<T>
непосредственно.
Даже документация Castle.ActiveRecord использует решение, которое вы нашли.
Смотрите здесь полный пример и некоторые другие решения: http://docs.castleproject.org/Default.aspx?Page=Type%20hierarchy&NS=Active%20Record
Я скопировал код на случай, если этот сайт исчезнет.
Базовый класс "Entity"
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);
}
}
Может быть, вы могли бы сделать:
public class Entity<T> : ActiveRecordBase<T> { }
public class Person : Entity<Person> {}
Сюда FindAll()
вернется Person[]