Reputation: 55
I'm trying to write a base class with some methods I want they are implemented in the classes that they inherit from this class.
In this example:
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)
{
...
}
}
this show the next error: "no suitable method found to override"
Is it possible to make this correct? How?
Upvotes: 0
Views: 1339
Reputation: 29244
This is similar to the accepted @jayGould answer, but with some additional tidbits to make it more inline with best practices.
I assume the target class for the service methods all have some commonality between them, and so it is useful to constrain ServiceBase<T>
to use this common ancestor:
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();
}
}
Additionally, an abstract
class should only have protected
constructors since they can only be called from derived classes.
Upvotes: 0
Reputation: 4702
You need to declare the type T
as part of your abstract class, and then pass a concrete type in your implementing 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);
}
And then implementing, pass your type (in your example, either classA
or classB
) as such:
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)
{
...
}
}
Upvotes: 1
Reputation: 351
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();
}
}
Upvotes: 2