【发布时间】:2014-04-25 09:21:58
【问题描述】:
我有一个存储库类,它使用 NPoco/PetaPoco 来访问从通用 content 表中读取的数据。
create table Content (
Id int not null identity primary key,
Type tinyint not null,
...
)
然后我有一个其他类型继承的抽象ContentBase 类。继承类型之间的主要区别是该类型 DB 列值的值。对于每个具体的内容类型,它们确实有一些额外的列,但这与这里无关。
所以。为了让我的存储库类返回任何我想写一个方法的实际具体类:
public TContent Create<TContent>(string name, ...)
{
...
// SP executes a few insers and returns newly created data instance
return db.Single<TContent>(
new Sql.Builder.Append(";exec dbo.CreateContent @Type, @Name, ...", new {
Type = TContent.Type, // this is the problem
Name = name,
...
}));
}
如您所见,我需要我的基本抽象类定义一个静态成员,以获取应该可以通过泛型类型规范访问的实际类型值。而继承类要根据具体的类型实现来设置。
问题当然是在 C# 中没有 abstract static members 这样的东西。
我应该如何解决这个问题,以便我的存储库能够自行提供 Type 值,而无需我在调用中明确提供它?我只想在调用它时提供泛型类并取回正确的具体类型。
为什么必须是静态成员?
我的方法没有获得特定类型的对象实例,但它应该创建一个。这就是为什么我不能真正拥有一个实例成员 Type 并在执行我的存储库方法时从该成员中读取。
一个可能的开始
由于静态成员在所有实例之间共享,并且如果这是基类,则所有继承类共享相同的成员,除非该类是通用的。在这种情况下,我们会为每个泛型类型获得一个静态成员。
所以我正在考虑在基本抽象类和具体类之间添加一个额外的类:
public abstract class ContentBase
{
...
}
public abstract class ContentBase<TConcrete>
where TConcrete: ContentBase<ContentBase> // is this constraint ok?
{
public static ContentType Type = ???;
}
然后是具体的类:
public class ContentOne : ContentBase<ContentOne>
{
???
}
如前所述,我应该能够将我的存储库方法称为:
repo.Create<ContentOne>(name, ...)
此方法存储库中的何处应该能够访问调用提供的泛型类型的静态成员...
【问题讨论】:
-
这不是可以使用抽象工厂解决的吗,比如 Windsor 中使用的 TypedFactory? docs.castleproject.org/Windsor.Typed-Factory-Facility.ashx 在运行时确定解析对象的类型在哪里?
-
@sammy:类型可以在运行时解析,但泛型会给我编译时间解析。这样做我并没有真正受益。
标签: c# inheritance abstract member