gpt4 book ai didi

c# - 任何实现类似于 "abstract static member"的东西的方法

转载 作者:太空宇宙 更新时间:2023-11-03 15:58:22 24 4
gpt4 key购买 nike

我有一个存储库类,它使用 NPoco/PetaPoco 访问从公共(public)内容表中读取的数据。

create table Content (
Id int not null identity primary key,
Type tinyint not null,
...
)

然后我有一个其他类型继承的抽象 ContentBase 类。继承类型之间的主要区别是该类型数据库列值的值。他们确实有一些针对具体内容类型的额外列,但这与此处无关。

所以。为了让我的存储库类返回任何实际的具体类,我想编写一个方法:

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# 中没有抽象静态成员这样的东西。

我应该如何解决这个问题,以便我的存储库能够自行提供 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, ...)

在此方法存储库中的哪个位置应该能够访问调用提供的泛型类型的静态成员...

最佳答案

即使您有一个抽象的 ContentBase 类的想法,您也无法访问每个派生类的自定义行为;这是一个小测试,我试图看看你的想法是否可以使用:

public abstract class ContentBase<T>
{
public static Func<string> TypeLocator { get; set; }
static ContentBase()
{
TypeLocator = () => typeof(T).Name;
}

}

public class Content1 : ContentBase<Content1> {
private static string Content1Type = "The type of Content 1";
static Content1()
{
TypeLocator = () => Content1Type;
}
}

public class Content2 : ContentBase<Content2> {}

class Program
{
static void Main(string[] args)
{
Console.WriteLine("Content1.Type => " + GetObject<Content1>()); // Content1
Console.WriteLine("Content2.Type => " + GetObject<Content2>()); // Content2
}

private static string GetObject<TContent>() where TContent: ContentBase<TContent>
{
var typeLocator = typeof(ContentBase<TContent>).GetProperties()[0].GetValue(null, null) as Func<string>;
return typeLocator.Invoke();
}
}

你能得到的最好的是 TContent 的类型,这可能足以让你探索下面的映射命题。

我真的没有看到实现抽象静态成员的方法,但是您可以求助于一个在整个程序中作为单例存在的外部注册字典,它将用作您的 Type 之间的映射器和你的 Type.DBType

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 = RegisteredTypes[typeof TContent],
Name = name,
...
}));
}

关于c# - 任何实现类似于 "abstract static member"的东西的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22500649/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com