C#如何将子类作为父类中的泛型类型传递

huangapple go评论58阅读模式
英文:

C# How to pass child class as generic type in parent class

问题

public class BaseContext : DbContext
{
public BaseContext(string connectionString) : base(connectionstring)
{
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // THIS PART HERE
    var sqliteConnectionInitializer = new SqliteDropCreateDatabaseWhenModelChanges<BaseContext>(modelBuilder);
    Database.SetInitializer(sqliteConnectionInitializer);
}

}

Now I'd like to inherit from BaseContext without having to override OnModeCreating again, but I'm not sure how I'd get my child class to be passed as the generic template in the parent class?
I've tried

var sqliteConnectionInitializer = new SqliteDropCreateDatabaseWhenModelChanges<typeof(this)>(modelBuilder);

but that doesn't work (for reasons outlined here)

Is there an easy solution to this that I'm missing?

英文:

I'm working with a 3rd party library which provides a class that takes the current class from which I'm instantiating it as a generic. It looks something like this

public class BaseContext : DbContext
{
    public BaseContext(string connectionString) : base(connectionstring)
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // THIS PART HERE
        var sqliteConnectionInitializer = new SqliteDropCreateDatabaseWhenModelChanges&lt;BaseContext&gt;(modelBuilder);
        Database.SetInitializer(sqliteConnectionInitializer);
    }
}

Now I'd like to inherit from BaseContext without having to override OnModeCreating again, but I'm not sure how I'd get my child class to be passed as the generic template in the parent class?
I've tried

        var sqliteConnectionInitializer = new SqliteDropCreateDatabaseWhenModelChanges&lt;typeof(this)&gt;(modelBuilder);

but that doesn't work (for reasons outlined here)

Is there an easy solution to this that I'm missing?

答案1

得分: 1

如我在评论中提到的,我不完全理解你的目标。这对你是否有帮助呢?

创建一个负责创建新对象的工厂

public static class CustomSqliteFactory
{
    public static SqliteDropCreateDatabaseWhenModelChanges<T> Create<T>(T obj, DbModelBuilder modelBuilder)
        where T : BaseContext 
    {
        return new SqliteDropCreateDatabaseWhenModelChanges<T>(modelBuilder);
    }
}

你可以像这样使用它:

var sqliteConnectionInitializer = CustomSqliteFactory.Create(this, modelBuilder);

我用记事本编写了我的解决方案,希望没有语法错误。

编辑

以下是一个类似的示例,实现了你的目标(我仅创建了打印函数用于演示):

public class Parent<TChild>
    where TChild : Parent<TChild>
{
    protected SqliteDropCreateDatabaseWhenModelChanges<TChild> obj;

    public Parent()
    {
    }

    protected void OnModelCreating()
    {
        this.obj = CustomSqliteFactory.Create<TChild>();
    }
}

public class Child : Parent<Child>
{
    public void Print()
    {
        base.OnModelCreating();
        Console.WriteLine($"Child type: {this.obj.GetType().GenericTypeArguments.First()}");
    }
}

public static class CustomSqliteFactory
{
    public static SqliteDropCreateDatabaseWhenModelChanges<T> Create<T>()
        where T : Parent<T>
    {
        return new SqliteDropCreateDatabaseWhenModelChanges<T>();
    }
}

输出是:

var child = new Child();
child.Print();
// Child type: Child
英文:

As I mentioned in the comments, I don't completely understand your goal.
Would this be a solution for you?

Create a Factory that is responsible for creating a new object

public static class CustomSqliteFactory
{
	public static SqliteDropCreateDatabaseWhenModelChanges&lt;T&gt; Create&lt;T&gt;(T obj, DbModelBuilder modelBuilder)
		where T : BaseContext 
	{
		return new SqliteDropCreateDatabaseWhenModelChanges&lt;T&gt;(modelBuilder);
	}
}

And you can use it like:

var sqliteConnectionInitializer = CustomSqliteFactory.Create(this, modelBuilder);

I wrote my solution using notepad and I hope there is no syntax error


Edit

Here is a similar example that achieves your goal: (I have created the print function for demonstration purposes only)

public class Parent&lt;TChild&gt;
    where TChild : Parent&lt;TChild&gt;
{
    protected SqliteDropCreateDatabaseWhenModelChanges&lt;TChild&gt; obj;

    public Parent()
    {
    }

    protected void OnModelCreating()
    {
        this.obj = CustomSqliteFactory.Create&lt;TChild&gt;();
    }
}

public class Child : Parent&lt;Child&gt;
{
    public void Print()
    {
        base.OnModelCreating();
        Console.WriteLine($&quot;Child type: {this.obj.GetType().GenericTypeArguments.First()}&quot;);
    }
}


public static class CustomSqliteFactory
{
    public static SqliteDropCreateDatabaseWhenModelChanges&lt;T&gt; Create&lt;T&gt;()
        where T : Parent&lt;T&gt;
    {
        return new SqliteDropCreateDatabaseWhenModelChanges&lt;T&gt;();
    }
}

The output is:

var child = new Child();
child.Print();
// Child type: Child

huangapple
  • 本文由 发表于 2023年3月7日 23:48:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75664206.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定