How do you deal with function overrides with different types of results?

The most obvious case of the problem is the Clone function (only the guys EXAMPLE ). Let's say you have BaseClass and DerivedClass - if I don’t miss something, in both functions (Clone per each of the class) you create BaseClass and DerivedClass respectively, but actually return an object. This is a problem if you want to work with a "real" class.

So far I see only two workarounds:

1. each time I bring the result of the function to the corresponding class

var real_stuff = (RealStuff)x.Clone(); // I want real stuff 

2. provide a second function, so you will have Clone (if you work at the base class level) and CloneThis (the result will change from class to class, if you want to work in this class level)

  public override object Clone() { return CloneThis(); } public RealStuff CloneThis() { return new RealStuff(this); } 

The first is ugly, the second is tiring.

QUESTION : how do you deal with this problem?

Another thing is to comment on this if you want - why, when is the redefinition of function signature verification so strict? In addition, "because it was designed that way" or "Beloved Eric Lippert," because each function requires ... ";-) I do not see technical (and logical, etc.) problems that allow overriding the function with the modified result type IF, the result of the override function is obtained from the original type of the result of the function.

Example:

  class ClassA { public virtual ClassA GetIt() ... } class ClassB : ClassA { public override ClassB GetIt() ... } 

This is currently not the right code, but I think it could technically be because ClassB is derived from ClassA. And whatever you do with the output, the "receiver" expects ClassA, so ClassB completely fills this requirement.

So you can write:

  ClassA class_a_b = new ClassB(); ClassB class_b_b = new ClassB(); ClassA result1 = class_b_b.GetIt(); ClassA result2 = class_a_b.GetIt(); ClassB result3 = class_b_b.GetIt(); // incorrect, derived GetIt would be called OK, // but the signature is taken from ClassA ClassB result4 = class_a_b.GetIt(); 

I also do not think that with such opportunities someone will be surprised by the behavior, IMHO this is agreed.

Please keep your answers on the topic, "You cannot use ICloneable" NOT on the topic. Thanks.

+4
source share
1 answer

Check out these two questions:

Basically, a way to handle this is to define a common interface with the appropriate return type, e.g.

 interface ICloneable<T> { T Clone(); } 

This, however, does not allow the interface to be used as a base type, because ICloneable <ClassOne> and ICloneable <ClassTwo> are two different things.

It would be “technically possible” to have functions that differ only in the inverse type, and infact CLR allows this, but C # does not, perhaps because it would be impossible to guess the correct overload for the call. (Actually, with C # you can do this using implicit operator statements: they are compiled for functions with the name op_Implicit and with a different return type).

+3
source

All Articles