如何在抽象中使用泛型 class

How to use generic types in abstract class

我正在尝试使用一些方法编写基础 class,我希望它们在继承自此 class 的 classes 中实现。

在这个例子中:

abstract public class ServiceBase 
{
    public ServiceBase()
    {
    }

    abstract public T Read<T>(string id);
    abstract public T Create<T>(T record);
    abstract public void Delete<T>(T record);
}

public class ServiceA: ServiceBase
{
    public Service(){}

    public override classA Read<classA>(string id)
    {
        ...
    }
    public override classA Create<classA>(classA record)
    {
        ...
    }
    public override void Delete<classA>(classA record)
    {
        ...
    }
}

public class ServiceB: ServiceBase
{
    public Service(){}

    public override classB Read<classB>(string id)
    {
        ...
    }
    public override classB Create<classB>(classB record)
    {
        ...
    }
    public override void Delete<classB>(classB record)
    {
        ...
    }
}

这会显示下一个错误:“找不到合适的方法来覆盖

是否可以改正?怎么样?

public class ClassA { }

public class ClassB { }

abstract public class ServiceBase<T> where T : class
{
    abstract public T Read(string id);
    abstract public T Create(T record);
    abstract public void Delete(T record);
}

public class ServiceConcrete1 : ServiceBase<ClassA> 
{
    public override ClassA Read(string id)
    {
        throw new NotImplementedException();
    }
    public override ClassA Create(ClassA record)
    {
        throw new NotImplementedException();
    }
    public override void Delete(ClassA record)
    {
        throw new NotImplementedException();
    }
}

public class ServiceConcrete2 : ServiceBase<ClassB>
{
    public override ClassB Read(string id)
    {
        throw new NotImplementedException();
    }
    public override ClassB Create(ClassB record)
    {
        throw new NotImplementedException();
    }
    public override void Delete(ClassB record)
    {
        throw new NotImplementedException();
    }
}

您需要将类型 T 声明为抽象 class 的一部分,然后在您的实现中传递具体类型 class。

abstract public class ServiceBase<T> 
{
    public ServiceBase()
    {
    }

    abstract public T Read(string id);
    abstract public T Create<T>(T record);
    abstract public void Delete<T>(T record);
}

然后实施,传递您的类型(在您的示例中,classAclassB),如下所示:

public class ServiceB: ServiceBase<classB>
{
    public Service(){}

    public override classB Read(string id)
    {
        ...
    }
    public override classB Create<classB>(classB record)
    {
        ...
    }
    public override void Delete<classB>(classB record)
    {
        ...
    }
}

这类似于公认的@jayGould 答案,但有一些额外的花絮使其更符合最佳实践。

我假设服务方法的目标 class 在它们之间都有一些共性,因此限制 ServiceBase<T> 使用这个共同的祖先是有用的:

public interface IClass { }

public class ClassA  : IClass { }
public class ClassB  : IClass { }

abstract public class ServiceBase<T> where T:IClass
{
    protected ServiceBase() { }

    abstract public T Read(string id);
    abstract public T Create(T record);
    abstract public void Delete(T record);
}

public class ServiceA : ServiceBase<ClassA>
{
    public ServiceA() : base() { }

    public override ClassA Read(string id)
    {
        throw new NotImplementedException();
    }
    public override ClassA Create(ClassA record)
    {
        throw new NotImplementedException();
    }
    public override void Delete(ClassA record)
    {
        throw new NotImplementedException();
    }
}

public class ServiceB : ServiceBase<ClassB>
{
    public ServiceB() : base() { }

    public override ClassB Read(string id)
    {
        throw new NotImplementedException();
    }
    public override ClassB Create(ClassB record)
    {
        throw new NotImplementedException();
    }
    public override void Delete(ClassB record)
    {
        throw new NotImplementedException();
    }
}

此外,abstract class 应该只有 protected 个构造函数,因为它们只能从派生的 classes 中调用。