Calling the constructor of a subclass from a baseclass - c#

Say you have an abstract base class:
abstract class abstractBaseClass {
public abstractBaseClass(object argument);
public abstractBaseClass instanceMethod() {
//call the constructor of the concrete class here.
}
}
And you have a base class:
class baseClass {
public baseClass(object argument) : abstractBaseClass(object argument)
}
If you have an instance method on abstractBaseClass is there any way to call the constructor of that concrete class inside the instance method without resorting to reflection?
It seems to be reasonable to assume there is at least one constructor with the signature concreteBaseClass(object) on any given concrete base class.

If you have an instance method on abstractBaseClass is there any way
to call the constructor of that concrete class
You already do that, actually. Abstract class can not be initialized if not by it's derivates.
abstractBaseClass abs = new baseClass();
The real object type here is baseClass, so the ctor of it will be called by convention.
EDIT
if you mean construct *a new * real object that is hosted inside abstract reference (something that is mantioned by Sevy in comments), I would suggest, at this point, just use
override pattern. Something like this:
abstract class abstractBaseClass {
public abstract abstractBaseClass(object argument);
public abstract abstractBaseClass CreateMe();
}
class baseClass : abstractBaseClass
{
...
public override abstractBaseClass CreateMe(){
return new baseClass();
}
}
after use it like
abstractBaseClass newAbs = abs.CreateMe();
Something like this, just an idea.
You should figure out by yourself the real, concrete implementation that fits your needs.

If you mean, "can I just call new baseClass() inside of abstractBaseClass, then yes, you can.
If you mean "can I dynamically figure out what class inherits from me and new one up", then no, not without using reflection. You have no way of knowing if there are more than one types inheriting from you.
This is, by the way, a pretty weird scenario and sounds like it violates a whole lot of best practices for OOP. Perhaps you would be better off creating a factory class to create your objects?

Related

Forcing partial base Initialization (and methods) in Inherited Class Constructor C# (like abstract does to methods) - work around to do it

I am having a C# abstract class which have some methods to be implemented by its children.
Though it is so, the initialization values for those children consist of two parts: one which is the same as the parent, and another one which is unique to the children.
public abstract class parentClass {
public abstract bool IsInputValid(string input); //children must implement this
public parentClass () {
//Some shared initialization
}
}
If the class is not abstract we could do something like this to implement that
public class parentClass {
public parentClass (string input) {
//Some shared initialization
}
}
public class childClass : parentClass {
public childClass (string input) : base (input) {
//Some unique initialization
}
}
But that cannot be done using abstract class and some more, the method not need not to be implemented (since it is not abstract).
So I am in a dilemma here. On one hand, I want to have some base initialization called and on the other, I also want to have some methods enforced.
So my question is, how do we normally implement such case? On one hand it is enforcing some base initialization, and on another some methods.
Note: I am new to abstract class so I would be glad to receive any inputs regarding it.
Where do I declare wrongly (if any)? If we cannot do so, is there a way to get around to produce the same result (that is, to enforce the child class to use certain signature for constructor)?
There should be no need to enforce this. You say that the base class has some common initialization and the child classes have their own specialized initialization as well.
This is enforced already, if you have this:
public abstract class Base
{
protected Base(int value) { ... }
}
Then you have a couple of guarantees:
Nobody can construct an object of the type Base since it is abstract
Nobody can construct an object that inherits from Base without indirectly calling the only existing constructor of Base, that takes an int value parameter.
The last part there is important.
A child class can deal with this type of base constructor in at least three ways:
It can provide a constructor that looks identical save the name of it, just passing the value down to the base constructor:
public class Child : Base
{
public Child(int value) : base(value) { ... }
}
It can provide a constructor that has this parameter but has additional parameters to the child class constructor as well:
public class Child : Base
{
public Child(int value, string other) : base(value) { ... }
}
It can provide a constructor that doesn't have the parameter to the base class, but manages to compute this parameter:
public class Child : Base
{
public Child(string other) : base(other.Length) { ... }
}
The last part also handles the case where the child constructor has no parameters at all:
public class Child : Base
{
public Child() : base(new Random().Next(100)) { ... }
}
Regardless of which approach you use, it is impossible to call the base class constructor without passing a value for that parameter, hence you have enforce the following:
Child classes has to be aware of the base class constructor and its parameter
But you cannot, and should not, try to enforce the presence of a particular constructor with a specific signature.
Now, having said that, what if you want to create some sort of common way to construct two distinct child classes, that has such different constructors, in such a way that code that uses them doesn't need to know the specifics of either constructor?
Enter the factory pattern (Wikipedia):
In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.
(quoted text copied from entry paragraph in the Wikipedia-article)
Here's a way to abstract away the presence and knowledge of such different constructors and child classes:
void Main()
{
Test(new Child1Factory());
Test(new Child2Factory());
}
public void Test(IBaseFactory baseFactory)
{
Console.WriteLine("In Test(...");
var b = baseFactory.Create();
}
public class Base
{
public Base(int value)
{
Console.WriteLine($"Base.ctor({value})");
}
}
public interface IBaseFactory
{
Base Create();
}
public class Child1 : Base
{
public Child1(int value) : base(value)
{
Console.WriteLine($"Child1.ctor({value})");
}
}
public class Child1Factory : IBaseFactory
{
public Base Create() => new Child1(42);
}
public class Child2 : Base
{
public Child2(string name) : base(name.Length)
{
Console.WriteLine($"Child2.ctor({name})");
}
}
public class Child2Factory : IBaseFactory
{
public Base Create() => new Child2("Meaning of life");
}
Pay special attention to the Test(...) method, as this has no knowledge of which Base child it will get, nor how to construct such an object. If you later on add new child types from Base, you will have to provide new factories as well but existing code that uses these factories should not need to be changed.
If you want a simpler factory pattern all you have to do is replace the interface and factory classes with a delegate:
void Main()
{
Test(() => new Child1(42));
Test(() => new Child2("Meaning of life"));
}
public void Test(Func<Base> baseFactory)
{
Console.WriteLine("In Test(...");
var b = baseFactory();
}
Final note here. Since the factory pattern means you will have to create a different type that does the actual construction of the object you can enforce the signature of that other type, either by
Adding parameters to the Create method on the factory interface
Specifying a delegate that has parameters to the factory delegate
This means you can enforce the signature of "the creation process". Still, you cannot enforce the presence or signature of a particular constructor, but the constructor is just a means to an end, create an object, and with the factory pattern you can actually formalize this pattern in your code and thus you should get what you want.
You cannot enforce the signature or even existence of constructors of your derived classes. (or any class for that matter)
I'm afraid that's the end of the story. You aren't doing anything wrong, it's just not possible.
Since you can't override constructors in c#, you cannot enforce the existence of a certain constructor in the derived class .
This means:
a constructor cannot be abstract, virtual etc
constructors aren't polymorphically
You cannot have an abstract constructor, but neither is there any need to.
All you need to do is remove the "abstract" keyword from your parentClass and you should be good to go.

c# runtime polymorphism with abstract base class

I am trying to clean up an existing code base, and am having trouble with using a generic reference name to the different derived classes of an abstract class.
For instance:
public abstract class Base<T> : Utilities.CommonRequiredObject
{
protected List<T> RawContents = new List<T>();
.
.
public abstract void LoadContents(List<T> Contents); // Each Class needs to load and process differently
protected List<T> Contents;
public virtual void DoSomething() // Default here for common use. Defined in Each class for its specifics (if needed)
{
...
}
public abstract List<T> FunctionToGetContents();
}
public class FOO : Base<string>
{
public override void DoSomething() ...
public override List<string> FunctionToGetContents() ...
}
public class BAR : Base<byte>
{
public override void DoSomething() ...
public override List<byte> FunctionToGetContents() ...
}
Main Logic to try to use common variable. I want to create a new class to use, but want to use it then in a runtime polymorphic way. As the classes have the common functionality, and have overrides where needed, I want to be able to create an instance, and then use it:
IE: Base<T> ObjectToUse;
This way, I can simply refer to the ObjectToUse in the following code and call common methods. As I inherited some common routines from another base class, I am not sure if I can use an interface or not.
if(variable)
{
FOO ObjectToUse = new FOO();
}
else
{
BAR ObjectToUse = new BAR();
}
ObjectToUse.LoadContents(ObjectToUse.FunctionToGetContents());
ObjectToUse.DoSomething();
...
Edit:
Based on the comments I received quickly (thanks again everyone) would it be better than to remove the Generic (Base<T>) and have the classes all of type Base(), then I could define the ObjectToUse simply as Base ObjectToUse; I believe.
This cannot be done.
By utilizing a reference that requires a generic type parameter, you must give it one. You could utilize dynamic here so that the type is run-time evaluated, but thats the best you will get.
Even utilizing something like a template method pattern, you would need to specify the generic type argument. If you just want the DoSomething method for this, it would need to be promoted to a higher base class (or an interface) so you could hold a reference to that type, and call that (non-generic) function.
To your comment, the solution I would take is this; refactor the common code into a template method pattern within the base class. Then have the "triggering" function be a non-generic inherited member from a non-generic base class (or interface). Now, you can hold a reference to that type, and invoke the template method to cause the other calls to occur.
public void DoAwesomeStuff() //inherited from non-generic parent or interface
{
LoadContents(FunctionToGetContents());
DoSomething();
}
Then:
IDoesAwesomeStuff ObjectToUse = new FOO();
ObjectToUse.DoAwesomeStuff();

why abstract class can have a instance method?

We know if a class has an abstract method it will be abstract . It can't get an instance. But why can have an instance method? Does it have any meaning?
public abstract class AbsClass
{
public abstract void GetA();
public void Getb()
{ }
}
Not every method in an abstract class has to be abstract - when you derive from the class, the derived classes will inherit the non-abstract methods from the base class. It's extremely common to want to provide functionality in the base class that is common to all the derived classes (in fact, it's good programming practice to pull shared functionality up to the base class to avoid duplicating code in the various derived classes). It's also extremely common to want to provide "default" functionality in the base class that can then be overridden by individual derived classes.
The fact that you can't instantiate the base class itself doesn't matter - the non-abstract methods from the base class are called on instances of (non-abstract) derived classes.
Yes, it has a meaning.
It will be available for use in any derived class that does not explicitly implement it itself.
Example of a derived class:
public abstract class AbsClass
{
public abstract void GetA();
public void Getb()
{ }
}
public class DerivedClass : AbsClass
{
}
The following code will execute the abstract class's Getb() code:
var derivedClass = new DerivedClass();
derivedClass.Getb();
(Note that in the example above, the code wouldn't compile unless your derived class implemented GetA(), as it's declared as abstract, and therefore must be implemented in any concrete derived class)
Yes, it is perfectly well defined. It can't be invoked until you have an instance, which in turn indicates that you must have a concrete sub-type, but once you do the method is perfectly usable, for example:
AbsClass foo = new ConcreteClass();
foo.Getb();
Or indeed:
ConcreteClass foo = new ConcreteClass();
foo.Getb();
(since the sub-type inherits any types defined on base-types)
It is quite common for such methods to themselves use the abstract or virtual methods of the type - or indeed to be virtual.
The method will be the implementation for a concrete class that derives from AbsClass. Abstract means you can't create an instance of the class, not that it can't have any methods with implementation. You can also have instance data members in an abstract class.
As an example:
public class MyAbsClass : AbsClass
{
}
MyAbsClass mine = new MyAbsClass();
mine.Getb(); //This would call the implementation in AbsClass
If AbsClass were an interface, however, no implementation would be allowed.

Can you mock an object that implements an interface AND an abstract class?

Is it possible to use Moq to mock an object that implements an interface and abstract class?
I.e.:
public class MyClass: SomeAbstractClass, IMyClass
Can you mock this?
You can mock any interface, and any abstract or virtual members. That's basically it.
This means that the following are absolutely possible:
var imock = new Mock<IMyClass>();
var aMock = new Mock<SomeAbstractClass>();
If the members inherited from SomeAbstractClass aren't sealed, you can also mock MyClass:
var mcMock = new Mock<MyClass>();
Whether this makes sense or not depends on the implementation of MyClass. Let's say that SomeAbstractClass is defined like this:
public abstract class SomeAbstractClass
{
public abstract string GetStuff();
}
If the GetStuff method in MyClass is implemented like this, you can still override it:
public override string GetStuff()
{
return "Foo";
}
This would allow you to write:
mcMock.Setup(x => x.GetStuff()).Returns("Bar");
since unless explicitly sealed, GetStuff is still virtual. However, had you written GetStuff like this:
public override sealed string GetStuff()
{
return "Baz";
}
You wouldn't be able to mock it. In that case, you would get an exception from Moq stating that it's an invalid override of a non-virtual member (since it's now sealed).
Your question does not really make sense. Moq can be used to mock abstract classes and interfaces. Since MyClass is neither then you cannot create a mock of it.
I don't think this is a problem though, since consumers of your MyClass instance will probably be expecting a SomeAbstractClass or an IMyClass instance and not a MyClass instance. If indeed they expect a MyClass instance, then you need to make some abstraction on top of it. This can be achieved by either having SomeAbstractClass implement the IMyClass interface, or by having the IMyClass interface expose the methods and properties of SomeAbstractClass.

How to return generic abstract class?

I have something like this:
abstract class BaseClass<T>
{
protected BaseClass(){}
}
class Class1 : BaseClass<Class1>
{
public static Class1 Instance = new Class1();
private Class1(){}
}
class Class2 : BaseClass<Class2>
{
public static Class2 Instance = new Class2();
private Class2(){}
}
...
public BaseClass<T> Method<T>(int z) where T: BaseClass<T>
{
switch(z)
{
case 1:
return Class1.Instance;
case 2:
return Class2.Instance;
}
}
That is very important that those classes cannot be instantiated since their construstors are private so we cannot do like
public BaseClass<T> Method<T>(int z) where T: BaseClass<T>, new()
How can I use abstract class as return type ?? I just can not work this out. Would appreciate for any assisstance here.
It sounds to me like you can't really have the method be generic. For instance, what would happen if I called:
BaseClass<Class1> foo = Method<Class1>(2);
You need a single point of truth - either the type argument, or the normal argument. You can make it the method argument by having a non-generic base class (either by making the existing base class non-generic, or introducing a non-generic base class to that). Change the return type of Method to this non-generic base class.
abstract class BaseClass<T>
{
public abstract T Instance { get; }
protected BaseClass(){}
}
maybe? You can't inherit static stuff I believe...
On a closer look... I don't think what you are trying to do is even possible... what are you trying to do anyways?
A type constraint is a type constraint. You are trying to change the type constraint in the method kind of. which obviously doesn't work, and shouldn't work. I think you need to think of a different way of attacking your problem. Whatever it is...
Take a look at the factory pattern. Your factory can have a method on it to get the instance. The first time it's called, it creates the instance. On subsequent calls, it can return the already-created instance.

Categories

Resources