Why limit the return type to inherit methods and properties so that descendants are not allowed?

Given the following hypothetical situation:

class ClassParent { } interface IClassProvider { ClassParent Get(); } 

Why is it an illegal implementation of IClassProvider:

 class ClassChild : ClassParent, IClassProvider { ClassChild Get() { return this; } } 

It also does not work for inheriting properties and implementing a base class instead of an interface, as in the example.

ClassChild - ClassParent. Why doesn't it then compile? The compiler clearly knows the type of compilation time of the class, so the following works:

 void DoSomething(object o) { ... }; void DoSomething(ConcreteClass c) { ... }; DoSomething(new ConcreteClass()); //Calls the second overload of the method because of static type resolving 

In multi-level scenarios, this makes me have a bunch of proxy methods and it is useless to clutter up my code when the underlying situation is clear. Honestly, I cannot come up with any problems or ambiguities if this is supported. I would be pleased with the compile-time resolution (static), since it works with overloads in the second example.

Edit: I know that the compiler expects the following:

 class ClassChild : ClassParent, IClassProvider { ClassParent Get() { return this; } } 

and I know that this will work, I ask you to explain why it is not supported, or the scenario in which it will lead to a) problems or b) ambiguities is worse than overloads that are supported.

Edit 2: This seems to be another duplicate of the same old question, which the MS apparently answered in this SO question . I mark the @Euphoric post as an answer because it provided a name for the function that helped find the “solution”.

+4
source share
5 answers

I think the function you are looking for is called the covariant return type

As for the "why," this is not implemented, no one knows. IMO this function is not needed, so it is simply not implemented.

And especially in your case, this can be easily solved using an Explicit Interface Implementation

+4
source

IClassProvider Get() method expects its developers to return everything that inherits or is an instance of ClassParent .

You break the contract specified by the interface by telling your developer to only return objects of one particular subclass of ClassParent , which, due to the nature of single inheritance in classes, is the reason that it is not allowed.

+2
source

While not exactly your question, you can implement something like this:

 class ClassParent { } interface IClassProvider<T> where T: ClassParent { T Get(); } class ClassChild : ClassParent,IClassProvider<ClassChild> { public ClassChild Get() { return this; } } 

Or, more importantly (which gives you more type safety)

 public class ClassParent { } interface IClassProvider<T> where T : ClassParent, IClassProvider<T> { T Get(); } class ClassChild : ClassParent, IClassProvider<ClassChild> { public ClassChild Get() { return this; } } 

EDIT:

the second version is a bit safer because it does not compile:

 public class SomeOtherChildClass : ClassParent { } class ClassChild : ClassParent, IClassProvider<SomeOtherChildClass> { public SomeOtherChildClass Get() { return this; } } 

you could write something like this, so it is not quite perfect:

 public class SomeOtherChildClass : ClassParent, IClassProvider<SomeOtherChildClass> { //implementation } class ClassChild : ClassParent, IClassProvider<SomeOtherChildClass> { public SomeOtherChildClass Get() { return something; } } 

I'm not sure that type safety is exactly the right term. What I wanted to achieve is an object that can only be provided to them, the vendor implements.

+2
source

Now that makes sense.

The signature must match exactly, for example,

 class ClassChild : ClassParent, IClassProvider { ClassParent Get() { return this; } } 
+1
source

What is the problem with using an explicit interface implemented with Euphoric?

 class ClassChild : ClassParent, IClassProvider { public ClassParent IClassProvider.Get() { return Get(); } public ClassChild Get() { return this; } } 
+1
source

Source: https://habr.com/ru/post/1340438/


All Articles