Override an abstract class of a base class with template - c#

I have a Base class with a template. Within this class there is an abstract method with a return type of the type in the template (see below).
I wish to create a new class , Derived , which inherits from this Base class , which (as expected) must "override" that method.
My question is how do I declare and implement the Derived class and the "overridden" method ?
Thanks allot in advance,
Guy.
public abstract class Base<MyType>
{
protected abstract MyType Foo();
}
public class Derived : Base ?????
{
protected override MyType Foo() ?????
{
return new MyType();
}
}

Simply specify the actual type for the generic base class, i.e something like:
public class Derived : Base<MyType>
{
protected override MyType Foo()
{
// some implementation that returns an instance of type MyType
}
}
Where MyType is the actual type you want to specify.
The other option would be to keep the derived class as generic, so something like:
public class Derived<T> : Base<T>
{
protected override T Foo()
{
// some implementation that returns an instance of type T
}
}

You must specify concrete type for Base or make Derived also generic:
public class Derived : Base<int>
{
protected override int Foo();
{
return 0;
}
}
or generic version:
public class Derived<TMyType> : Base<TMyType>
{
protected override TMyType Foo();
{
return default(TMyType);
}
}

Declare it in the same way:
public class Derived<MyType> : Base<MyType>
{
protected override MyType Foo()
{
return new MyType();
}
}

Related

Set generic type property in derived classes

I have a generic type G<T> where T : A, where A is an abstract class. In each class B derived from A I want to have a field of type G<B>, without writing repetetive code, however I'm not sure if it's even possible. One way to do this would be
abstract class A
{
protected object g;
protected abstract void SetG();
public A()
{
SetG();
}
}
class B : A
{
protected override void SetG()
{
this.g = new G<B>();
}
public B() : base() {}
}
But this would mean a lot of repetetive code in every derived class. Is there a better way to do this?
You could add an extra abstract class in between:
public abstract class A<T> : A where T : A
{
protected override void SetG()
{
this.g = new G<T>();
}
}
...then, update your B declaration to:
public class B : A<B>
{
public B() : base() { }
}
I believe that what you are trying to do is a Covariant Conversion. See this MSDN article on using delegates and see if that works for you. Look in the section "Using Delegates with Covariant Type Parameters".
In your A:, create a delegate:
Func<G<A>> GetG;
Then, in your derived classes, set this func pointer to a function of type
Func<G<B>>
Bingo!

C# inherited class from generic as a type

I've got an issue with generics. I've those classes :
abstract class BaseTestClass<T> : where T : class, new()
{
//base test class implementation
public abstract void Run(BaseDataClass<T> data);
}
class BaseDataClass<T> : where T : class, new()
{
//base data class implementation
}
class DataA : BaseDataClass<SettingsA>
{
//some stuff
}
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
}
//Doesn't Work!
public override void Run(DataA data)
{
}
}
My question if why can't I use the inherited class in the abstract method ?
[EDIT]
The error at compilation is:
TestA does not implement inherited abstract member Run(BaseDataClass)
You can, but the BaseTestClass<SettingsA> base class simply does NOT have a method to override of the signature Run(DataA), but only one of the signature Run(BaseDataClass<DataA>).
The generic inheritance also means that the generic T type is the same.
You can implement this with an additional generic argument, Type-Safe and without cast:
internal abstract class BaseTestClass<T, Y>
where T : class, new()
where Y : BaseDataClass<T>
{
private T m_data;
//base test class implementation
public abstract void Run(Y data);
}
public class BaseDataClass<T> where T : class, new()
{
}
internal class TestA : BaseTestClass<SettingsA, DataA>
{
public override void Run(DataA data)
{
throw new NotImplementedException();
}
}
class DataA : BaseDataClass<SettingsA>
{
}
class SettingsA
{
}
This is type-safe because the constraint is
where Y : BaseDataClass<T>
If you don't need T directly in you base class, you can only use one generic parameter and remove T
Your second method does not compile because there is no method to be overriden by it, removing the override modificator will make your code compile.
If you want to have a method which will run only when the parameter is of type DataA, but still execute the interface method implementation, you can do this way:
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
}
public void Run(DataA data)
{
//dp some stuff
Run((BaseDataClass<SettingsA>)data);
}
}
But note that this is not bullet proof, you could miss boxed calls, the better way is do this way:
class TestA : BaseTestClass<SettingsA>
{
//Works!
public override void Run(BaseDataClass<SettingsA> data)
{
var myDataA = data as DataA;
if (myDataA != null)
{
//your parameter is a DataA;
}
}
}
It does not work because you cannot override one method with two methods. Take the override off of one of the methods in TestA, and it will all work. There's no point in overriding a single method twice, anyhow, within a single class.

Override abstract method with another one, having different parameters

I have an abstract class ClassA, with an abstract method that takes a paramter of type ClassB. Several classes derive from it. Now I add another project, which has similar functionality, but needs a slightly different base ClassA, to derive its several classes from. The main difference: The new base class, ClassC, shouldn't ClassB as argument, but another one, that's derived from B, ClassD. ClassC should then be used as base by several classes again.
Is this possible? This is more of a question out of curiousity. I know it is possible with generics, by doing this:
public abstract void Method1<T>(T parameter) where T : ClassB;
...
public override void Method1<ClassB>(ClassB parameter) {
Is it possible without generics? And is there any dowside to them, aside from having to type the type twice?
abstract class ClassA
{
public abstract void Method1(ClassB parameter);
}
class DerivingClasses1 : ClassA
{
public override void Method1(ClassB parameter)
{
// do something
}
}
// -------
abstract class ClassC : ClassA
{
// This would have to override Method1 of ClassA somehow,
// instead of overloading it.
public abstract void Method1(ClassD parameter);
}
class DerivingClasses2 : ClassA
{
public override void Method1(ClassD parameter)
{
// do something
}
}
// -------
class ClassB
{
}
class ClassD : ClassB
{
}
In my opinion, the best approach would be to override the base class method with a sealed implementation that invokes the overload with the new parameter type, thereby insulating the user from the type conversion.
abstract class ClassC : ClassA
{
public override sealed void Method1(ClassB parameter)
{
this.Method1(parameter as ClassD);
}
public abstract void Method1(ClassD parameter);
}
Edit: If used in production, you should perform proper type checking in order to avoid getting unexpected nulls:
abstract class ClassC : ClassA
{
public override sealed void Method1(ClassB parameter)
{
if (!(parameter is ClassD))
throw new ArgumentException(
"Parameter must be of type ClassD.", "parameter");
this.Method1((ClassD)parameter);
}
public abstract void Method1(ClassD parameter);
}
Just implement both methords in ClassC.
Override abstract method with another one, having different parameters
This is not really possible, however you could use a common interface:
interface IMyType {}
class MyTypeBase
{
public abstract void Method1(IMyType parameter);
}

C# How to set Generic type with abstract method

I have an abstruct class with abstract method, the method param is generic.
this is the param type declaration:
public class StepHandlerWrapper<T> where T : BaseStepDataModel{...}
this is the parent abstract:
this is actually the problem, I want the StepHandlerWrapper generic type to be dynamic on each implementaion:
public abstract class BaseStepHandler{
protected abstract HandlerResult Handle(StepHandlerWrapper<???????????????> );
}
these are 2 implementations Note the generic type on each one (different):
public class LoginHandler : BaseStepHandler {
protected override HandlerResult Handle(StepHandlerWrapper<LoginStepOneDataModel> wrapper){...}
}
public class RegularDemoAccountHandler : BaseStepHandler{
protected override HandlerResult Handle(StepHandlerWrapper<RegularDemoAccountStepOneDataModel> wrapper){...}
}
how do I make each implementation of the abstract method to be different?
You need to make BaseStepHandler generic as well:
public abstract class BaseStepHandler<T> where T : BaseStepDataModel {
protected abstract HandlerResult Handle(StepHandlerWrapper<T> wrapper);
}
public class LoginHandler : BaseStepHandler<LoginStepOneDataModel> {
protected override HandlerResult Handle(StepHandlerWrapper<LoginStepOneDataModel> wrapper) {...}
}
The 2 implementations are both DataModels, so why not make that an abstract class where both implementations derive from:
abstract DataModel {
}
class LoginStepOneDataModel : DataModel {
}
class RegularDemoAccountStepOneDataModel : DataModel {
}
public abstract class BaseStepHandler{
protected abstract HandlerResult Handle(StepHandlerWrapper<DataModel>);
}

How to infer a type in a base class dependant on the inheriting class at runtime without if statements?

I have this little OO problem..
abstract class MyAbstractBaseClass
{
MyHelperClassBase myHelperBaseClass;
protected method foo()
{
//QUESTION....... : when I am here I want to do this...
myHelperBaseClass = new MyHelperSubClass();
//OR...
myHelperBaseClass = new MyOtherHelperSubClass();
//HOWEVER ITS COMPLETELY CONDITIONAL ON THE BASE CLASS
//HOW DO I MAKE SURE THE CORRECT TYPE IS INSTANTIATED DEPENDANT ON
//THE BASE CLASS WITHOUT USING AN 'if' STATEMENT?
}
}
class MySubClass : MyAbstractClass {}
class MyOtherSubClass : MyAbstractClass {}
/////////////
abstract class MyHelperClassBase {}
class MyHelperSubClass : MyHelperClassBase, IMyHelper {}
class MyOtherHelperSubClass : MyHelperClassBase, IMyHelper {}
I want to be able to have a the type basically passed up but cant think of a slick way to do this. Should I just stuck an abstract property on the base class?
Your goals are somewhat unclear. If the goal is to associate a helper class with a specific implementation of the class, there are a couple of options.
You can use generics:
abstract class MyAbstractBaseClass<T> where T : MyHelperClassBase, new()
{
T myHelper;
protected void Foo()
{
myHelper = new T(); // This will be the appropriate subclass
}
}
// Derived classes become ...
class MySubClass : MyAbstractClass<MyHelperSubClass>
{
}
// Derived classes become ...
class MyOtherSubClass : MyAbstractClass<MyOtherHelperSubClass>
{
}
Alternatively, you could have an abstract property in the base class, and the subclasses could implement it:
abstract class MyAbstractBaseClass<T> where T : MyHelperClassBase, new()
{
MyHelperClassBase myHelper;
abstract protected Func<MyHelperClassBase> MyHelperClassBaseFactory { get; }
protected void Foo()
{
// Construct as needed...
myHelper = MyHelperClassBaseFactory();
}
}
// Derived classes implement...
class MySubClass : MyAbstractClass
{
protected override Func<MyHelperClassBase> MyHelperClassBaseFactory
{
get { return () => new MyHelperSubClass(); }
}
}
The older OO way of solving this (without generics) involves a virtual or abstract method on the base that the derived classes must implement. This is pretty common in parallel hierarchies like your example:
abstract class MyAbstractClass{
MyHelperClassBase myHelper;
protected void foo() {
myHelper = createHelper();
}
protected abstract MyHelperClassBase createHelper();
}
class MySubClass : MyAbstractClass{
protected override MyHelperClassBase createHelper(){
return new MyHelperSubClass();
}
}
class MyOtherSubClass : MyAbstractClass{
protected override MyHelperClassBase createHelper(){
return new MyOtherHelperSubClass();
}
}
Generics come in very handy, but sometimes it's good to know this way, too.

Categories

Resources