Still missing constructor inheritance / static method inheritance #6315
Replies: 5 comments 7 replies
-
IMO it doesn't make a lot of sense to force all derived types within a hierarchy to accept the same state on construction as that assumes that you can define a lowest-common denominator of state that would apply to every derived type. It makes it impossible for a derived type to have additional required state as you cannot force construction to supply them. Most type hierarchies aren't like your HTML DSL example, and even in that case I don't think it makes sense to have all HTML elements within the DSL accept the same state. If C# were to do anything here I think it'd make more sense for it to provide a similar feature to C++ where you can specify that base constructors are "copied" into the derived type. You could accomplish that today with source generators.
I'm going to assume that it was about making it easier to discover helper static methods declared on a type within a hierarchy without having to remember exactly which type declared that static method, e.g. |
Beta Was this translation helpful? Give feedback.
-
It makes a lot of sense. Derived types can supply additional constructors and chain in others. Class families don't share state but behavior and therefore constructors. In PHP it works as follows: Heading extends Element {
// factory method
public static function InstanceByLevelContent(int $level, string $content):static {
return static::InstanceByContent($content) // call base constructor
->LevelSet(1) // fluent interface
;
}
public function LevelSet(int $i):static {
...
return $this;
}
} |
Beta Was this translation helpful? Give feedback.
-
No, thats what the parameters are for. This is just a very short & simple example. The whole library is very fluent to allow fast creation and configuration of HTML objects. The constructor initialization in C# is not powerful enough, so we need methods. But the important thing here is: every Element brings a InstanceByContent() method - and that totally makes sense. |
Beta Was this translation helpful? Give feedback.
-
Sorry for the late replies. Github didnt notify me on comments. And we just got a new project with c# so I wanted to revive the proposal. |
Beta Was this translation helpful? Give feedback.
-
Closing this in favor of #8243 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
This continues / reopens #2841.
Still missing is the ability to add constructors to a larger class hierarchy without having to resort to crude language constructs. PHP and Swift support this much more elegantly with static inheritance + covariance or constructor inheritance.
Simply explained using the example of an HTML DSL.
This is how it should look:
This is what would be needed:
Every derived class needs them.
Proposed solution so far:
static Element.create(...) -> Element
would not be inherited tostatic Paragraph.create(...) -> Paragraph
but to something completely useless and unwanted:static Paragraph.create(...) -> Element
.new Element<Paragraph>(...)
are bulky ugly, because they require repetition and knowledge of the class hierarchy. This is especially important in a case where it would be necessary to call a constructor in the middle of the class hierarchyAdvancedElement
because it performs initialization that the baseElement
class does not know about.PHP / Swift do this with simple static methods with a covariant return type of "Self" or "static", which can be used as constructors or factory methods. Btw, this shows, that they are used, interpreted and handled as equal concepts.
Element(string content): self or static
, and these methods are inherited with correct return types too.C# "inherits" those static methods as well officially, but under the hood rewrites the calls to the wrong original method.
Paragraph::create(...)
would be compiled toElement::create(...)
. However if I copied the method from Element to Paragraph it would work but in a class hierarchy that would mean lots of stupid copy&paste everywhere.So far also nobody could explain what good it is to be able to call a static
Paragraph.create(...)
on an inherited class, but the compiler makesElement.create(...)
out of it. This is completely counterintuitive and the code does not reflect what really happens. The behavior changes completely, if - explained above - I copy the method over to Paragraph.Beta Was this translation helpful? Give feedback.
All reactions