Proposal: Static inheritance a.k.a. delegator types #3177
Unanswered
IS4Code
asked this question in
Language Ideas
Replies: 3 comments
-
The source generators proposal would be perfect for handling this and would not require any language changes. |
Beta Was this translation helpful? Give feedback.
0 replies
-
Using the |
Beta Was this translation helpful? Give feedback.
0 replies
-
For alternative syntax, see how Kotlin does this ("delegation"): https://kotlinlang.org/docs/reference/delegation.html. E.g. interface Thing {
fun doSomething()
}
class C(impl: Thing) : Thing by impl
// Instances of type C now have all the members of `Thing`
fun main() {
val c : C = null!!
c.doSomething()
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
This proposal solves two issues: the inability to inherit from sealed classes or value types, and the need to delegate certain calls to a pre-supplied object.
In addition to the normal types a type can inherit from, any type in the list can be prepended with the
static
keyword which turns inheritance into composition. A field is added to the type with the specified type, and all public instance and explicit interface implementation methods, properties, and events from the inherited type are copied to the inheriting type and proxied to the field:The
static base(T)
keyword can be used to access the special field, and unlike thebase(T)
from its own proposal, the field can be assigned to and so the programmer can specify how the field shall be inicialized (if at all). If the field remains uninitialized, the default value is used, in which caseNullReferenceException
is thrown in case of a reference type.The members from the inhered type shall be copied without any additional attributes, like
virtual
orsealed
. The actual attributes can be specified together with the statically inherited type:This makes all members "inherited" from
A
protected, and all the methods shall also be virtual.If the inherited type implements an interface explicitly, and the interface is also shared by the inheriting type, the explicit interface implementation can be used:
In addition to implementing interfaces with this mechanism, overriding abstract classes is also possible. This allows the possibility to override a base class with an instance of the base class itself:
The
override
keyword should be applicable in all cases, even if one (or all) of the methods cannot override anything, in which case it is simply ignored. If the supplied accessibility keyword is in conflict with anoverride
method, the original accessibility attribute is used instead (i.e.private override static A
will make all methodsprivate
except those that actually override something). With this way, creating a class like the existingTypeDelegator
is really straightforward:This makes it very easy to create something like a custom type system with implementations of
Type
,MethodInfo
,PropertyInfo
etc. that refer to existing instances and only add a small number of extensions.There is also nothing that would prevent generic parameters to be used as well:
The members are copied from all constraints that are specified on the generic parameter.
With
dynamic
Perhaps
dynamic
can be also added into the mix in two ways.First, simply inheriting from
static dynamic
alone (what a nice combination of keywords) could make the class itself dynamic (properly implementingIDynamicMetaObjectProvider
) and delegating all calls to a user-suppliedstatic base(dynamic)
field. Not sure if this is all that useful though.Second, something like
static dynamic IEnumerable
could be used, which would copy all instance members fromIEnumerable
like before, but makestatic base(IEnumerable)
of typedynamic
instead ofIEnumerable
.This option seems much more easier to implement, as it simply means changing the type of the field. Perhaps a general mechanism can be used instead though, something like
static IEnumerable(dynamic)
wheredynamic
could be replaced with any other type, where the copied members would be tried to be accessed by name, but I am not sure about the usability of that.Beta Was this translation helpful? Give feedback.
All reactions