Right now in my code, I have an abstract class, which contains a nested class. In the constructor of every class implementing my abstract class, I will have to construct an instance of the nested class, and pass a reference to the current object to the nested class, as demonstrated below.
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo()
{
this.SpecialStuff = new SpecializedClass(this, "stuff"); // <= This is the issue
// More stuff
}
}
As you can see, whenever I need to call new SpecializedClass()
, I have to pass a reference to this
. Is there a way to do this automatically, so the classes inheriting from MainClass
don't need to keep passing references down?
CodePudding user response:
There answer is basically no. The stack frame does not contain a reference to the calling object (if any), there is no way to get at it fundamentally unless you pass it in, or want to walk the stack (bad idea).
There are however situations where you can use expression trees for more complicated less trivial problems. however, they hardly apply here, and would be more printable characters anyway.
I guess another approach would be an extension methods, however you are just kicking the this
ball up the road and creating more code for no good reason
Which leaves with a instance method or base class...
Lastly, although common, I would double check you actually need the calling object. This can easily brush up on design issues such as the Single Responsibility principle (SRP) and Separation of concerns (SOC) among others
All things being equal, if you need it then just pass it in.
CodePudding user response:
No, this is not possible.
Think about it: You could run SpecialStuff = new SpecializedClass(this, "stuff");
in a static function. Then what would the value of this
be?
It seems that you could push that functionality into the base abstract class.
Now you only need to call the SpecializedClass
and pass this
once
public abstract class MainClass
{
public SpecializedClass SpecialStuff { get; init; }
public MainClass(object stuff)
{
this.SpecialStuff = new SpecializedClass(this, stuff);
}
/* General stuff happens here*/
public class SpecializedClass
{
private MainClass _parent;
public SpecializedClass(MainClass parent, object stuff)
{
this._parent = parent;
// Do stuff...
}
/* More specialized stuff happens here.*/
}
}
public class Foo : MainClass
{
public Foo() : base("stuff")
{
// More stuff
}
}