从泛型超类定义中获取正确的子类方法

本文关键字:类方法 获取 泛型 超类 定义 | 更新日期: 2023-09-27 18:36:30

如何在多个子类中实现超类中定义的泛型方法?我需要由调用子类实例的类型决定正确的子类方法:

var someClassObj = new SubClass();
var = someClassObj.BuildList(v1, v2);
public abstract class SomeBase
{
    public List<T> BuildList<T>(int v1, int v2)
    {
        var results = new List<T>();
        for (int i = v1; i < v2; i++)
        {
            results.Add(AddItem<T>());
        }
        return results;
    }
    protected abstract T AddItem<T>();
}
public class SubClass : SomeBase
{

    protected override BusinessThing AddItem<T>()
    {
        var entity = new BusinessThing();
        entity.Name1 = "1";
        entity.Name2 = "2";
        entity.Name3 = "3";
        return entity;
    }
}
public class BusinessThing
{
    public string Name1 { get; set; }
    public string Name2 { get; set; }
    public string Name3 { get; set; }
}

以上不构建:覆盖方法"T SomeBase.AddItem()"时无法更改返回类型

从泛型超类定义中获取正确的子类方法

你可以使基类成为泛型而不是它的方法:

public abstract class SomeBase<T>
{
    public List<T> BuildList(int v1, int v2)
    {
        var results = new List<T>();
        for (int i = v1; i < v2; i++)
        {
            results.Add(AddItem());
        }
        return results;
    }
    protected abstract T AddItem();
}
public class SubClass : SomeBase<BusinessThing>
{
    protected override BusinessThing AddItem()
    {
        var entity = new BusinessThing();
        entity.Name1 = "1";
        entity.Name2 = "2";
        entity.Name3 = "3";
        return entity;
    }
}

如果你不想像 Daniel 建议的那样拥有泛型类,你也可以告诉编译器 T 正在使用 where 子句来限制泛型类型:

public abstract class SomeBase
{
    public List<T> BuildList<T>(int v1, int v2) where T: BusinessThing
    {
        var results = new List<T>();
        for (int i = v1; i < v2; i++)
        {
            results.Add(AddItem<T>());
        }
        return results;
    }
    protected abstract T AddItem<T>() where T:BusinessThing;
}
public class SubClass : SomeBase
{
    protected override T AddItem<T>()
    {
        var entity = new BusinessThing();
        entity.Name1 = "1";
        entity.Name2 = "2";
        entity.Name3 = "3";
        return (T)entity;
    }
}

然后按如下方式使用它:

var someClassObj = new SubClass();
var list = someClassObj.BuildList<BusinessThing>(5, 7);

这也允许您使用派生的 ConcreteBusinessThing 类,该类派生自 BusinessThing,该类也应该使用以下方法工作:

public class SubClass : SomeBase
{
    protected override T AddItem<T>()
    {
        var entity = new ConcreteBusinessThing();
        entity.Name1 = "1";
        entity.Name2 = "2";
        entity.Name3 = "3";
        return (T)(object)entity; // ugly cast but is always ok
    }
}

并用以下命令调用它:

var someClassObj = new SubClass();
var list = someClassObj.BuildList<ConcreteBusinessThing>(5, 7);