Habit when using overloaded methods with string [] parameters and inheritance

I had a class like this

public class Child { public string ToXml() { return "Child : ToXml()"; } public string ToXml( params string[] fields ) { return "Child : ToXml(...)"; } } 

instantiating the Child class and calling ToXml () returns the first overloaded function, which was beautiful and dandy.

 var obj = new Child(); Console.WriteLine( obj.ToXml() ); 

Output:

 Child : ToXml() 

But when I added the Parent class and changed the Child class to this:

 public class Parent { public virtual string ToXml() { return "Parent : ToXml()"; } } public class Child : Parent { public override string ToXml() { return "Child : ToXml()"; } public string ToXml( params string[] fields ) { return "Child : ToXml(...)"; } } 

The output has changed to the following:

 Child : ToXml(...) 

My question is: why is this behavior? (I am using VS2010 using .NET 3.5)

I kind of “fixed” this problem by changing the second overloaded function: (I took out the params keyword

 public class Child : Parent { public override string ToXml() { return "Child : ToXml()"; } public string ToXml( string[] fields ) { return "Child : ToXml(...)"; } } 

Which brings me to my second question (let me know if I have to split this into 2 different posts), what is the difference between the functions

 ToXml( params string[] fields ) 

and

 ToXml( string[] fields ) 

They both work when I call functions like this:

 var obj = new Child(); Console.WriteLine( obj.ToXml( new [] { "foo", "bar" ) ); 
+4
source share
4 answers

For your first question, this is by design :

For example, the set of candidates for calling a method does not include overridden methods (section 7.3), and methods in the base class are not candidates if any method in the derived class is applicable (section 7.5.5.1).

For your second question, the params modifier makes this parameter act as the varargs parameter, i.e. it can take several parameters separated by commas, and the array is created implicitly by the compiler.

+4
source

why is this behavior?

It's unclear what you mean by “like this,” so first let me characterize the behavior correctly. The behavior you experience is: for the purpose of overload resolution, the applicable candidate method on the derived type is always better than the applicable candidate method on the base type. Moreover, a virtual method is considered as a method of a type that declares it, and not a type that overrides it.

It’s also not clear what you mean by “why”? “Why” questions are hard to answer; in a sense, the question already answered: why does the compiler demonstrate this behavior? Because this is a consequence of the above rules for breaking permission congestion. But then you can say that the question was being asked; the question now is "so why is the specification written that way?"

The specification was written that way because it reduces the problem of a fragile base class. The problem with a fragile base class is when you have two commands, one of which is working on the base class and one is working on the derived class. If the team working on the base class introduces a new method, then this should not change the behavior of code using the derived class. If so, then changing the base class is “broken” by the derived class. C # was carefully designed to troubleshoot a fragile base class.

Even getting out of the problem of a fragile base class, it makes sense to determine the priority of a method on a derived class. Derived class developers have more information than base class developers. They know that they have a banana in their hand; base class developers only know that they have Fruit. The challenge should go according to a method written by developers who had more information when possible.

Then you could say "well, I asked the question again, now I want to know why it is important to mitigate the problem of a fragile base class." Instead of continuing this endless regression, I will just leave it; if you want to know more, ask a less vague question.

If you are interested in mitigating the failure of a fragile base class, consider reading my long series of articles on it .

what is the difference between the functions

The difference is that one potential candidate is in its expanded form or in its normal form, while the other has only one candidate candidate form.

+7
source

Not sure what is going on in your first question, but to answer the second, the params allows the calling code to call a function with a variable number of parameters, not just an array. So you can do:

 obj.ToXml("foo", "bar", "baz"); 
+1
source

I believe that your first question is answered by the ambiguity around calling ToXML with no arguments. With these 2 definitions, you can call any method (because of the params keyword, which also allows you to not pass any parameters).

I think the reason that ToXml is called is the method of the Child class, which is good because it is a method of the child class, not one that is inherited by the parent class and then overridden.

Note. If you defined a ToXml that takes no arguments, this would be the preferred method to execute.

0
source

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


All Articles