Reputation: 637
I have a parent class with a lot of members. When constructing its child class, I'd like to avoid referencing the base constructor with a bunch of input arguments if possible.
Is it possible to construct a child class by inputting an object of its parent class, and automatically have all of the parent members defined by the parent class object, without referencing the base constructor or each member individually?
Something like:
class parent {
$name
$type
parent ($processName, $processType ) {
$this.Name = $processName
$this.Type = $processType
}
}
PS>$newParent = [parent]::new('FirstJob', 'report')
PS>$newParent.Name
FirstJob
class child : parent {
$order
child ( [parent]$process, $processOrder ) {
$this.type = $process.type
$this.order = $processOrder
}
}
PS>$newChild = [child]::new($newParent, 1)
PS>$newChild.Name
FirstJob
Where the member Name would have been automatically defined in the child object via the input of the parent object.
This isn't working for me, as the child class seems to require a reference to the base constructor. Is it possible to avoid this? With 1 member it looks trivial to reference the base class constructor (or redefine the parent members in the child constructor), but I have about 8-10 members and would like to keep the code in the child class focused on its construction.
What I've done as a workaround is to overload the parent constructor with a single-argument input, i.e., the following:
class parent {
$name
$type
parent ($processName, $processType ) {
$this.processName = $processName
$this.processType = $processType
}
parent ( [parent]$parent ) {
$this.name = $parent.name
}
}
And then I construct the child class with the new base constructor in parent:
class child : parent {
$order
child ( [parent]$process, $processOrder ) : base ($process) {
$this.type = $process.type
$this.order = $processOrder
}
}
PS>$newChild = [child]::new($newParent, 1)
PS>$newChild.Name
FirstJob
This works okay, but it would be cool if I didn't have to list out the member mappings in the new parent constructor. I'd like to minimize code in the parent class definition if I can, just to keep things minimal and easier to read.
Is there any kind of automatic member-inheritance from a parent class available in PowerShell?
In the parent base constructor above, I even crossed my fingers and tried $this.* = $process
😂 Doesn't work of course.
Upvotes: 0
Views: 521
Reputation: 174485
You can use reflection to enumerate all the properties declared by the base class in the copy-constructor:
class Parent
{
[string]$Name
[string]$Type
Parent([string]$ProcessName, [string]$ProcessType){
$this.Name = $ProcessName
$this.Type = $ProcessType
}
# define copy-constructor that blindly copies all property values from reference object to itself
Parent([Parent]$referenceObject) {
foreach($Property in [Parent].GetProperties()){
$Property.SetValue($this, $referenceObject.$($Property.Name))
}
}
}
Here, [Parent].GetProperties()
will return metadata for every property belonging to [Parent]
(eg. [string]$Name
and [string]$Type
) and allow us to copy the values of those two from the reference object.
Now you simply pass the parent instance to the copy-constructor when constructing a child instance and be done with it:
class Child : Parent
{
$Order
Child([Parent]$ParentProcess, $ProcessOrder) : base($ParentProcess)
{
$this.Order = $ProcessOrder
}
}
class AnotherChild : Parent
{
$SomethingElse
AnotherChild([Parent]$ParentProcess, $ProcessInfo) : base($ParentProcess)
{
$this.SomethingElse = $ProcessInfo
}
}
Upvotes: 2