Why do some methods in C # return narrow data types when a wider data type makes sense?

I consider myself a good average .Net developer, and Ive got a decent understanding of all the concepts and terminologies in C # after I worked on it for the last 3 years. Nevertheless, I have this question, and I apologize if this seems like a silly and silly question. I want to know why some methods in the Framework class library return narrow data types when a wider data type will make more sense, and we should later cast it to the data type that interests us. I would like to give after two examples to support my question:

  • Label Label1 = (Label)Grid.FindControl("Label1");
    In this example, why FindControl returns an instance of type Control, and we must attribute it to type Label. It could return an instance of type Label, since we are passing a valid identifier declared in the markup in the method argument.

  • protected override object SaveViewState()
    In this example, the return object we should use may be a string.

I am sorry again if my question is confused. All I want to know is why such scripts return wider types when they could return narrow types, and this could avoid the extra step of casting to the type we need.

+4
source share
4 answers

This is because when you design a structure, you need to work as at a general level as possible, or at an abstract level if you want. Returning to the most possible base class, in this case it creates an abstraction that can support almost everything. Imagine:

 Label label1 = (Label)Grid.FindControl("Label1"); TextBox textBox1 = (TextBox)Grid.FindControl("TextBox1"); Calendar calendar1= (Grid)Grid.FindControl("Calendar1"); 

There is only one method to get a control from a Grid . The caller knows that this is accurate, so he switches to the known type.

If I, as a framework developer, would like to make special methods for Label , TextBox , Calendar , I would need to add one method for each type. I think you will agree that this is simply unthinkable from the point of view of the frame designer. From the point of view of a developer who needs to develop a common infrastructure for other developers.

+5
source

First, you’ve turned around a bit since the “wider” one is usually used for less derived types. For instance. Control wider than Label , because the definition covers everything that comes from Control , which includes Label , as well as other things.

Regarding the urgent issue. There are times when you can argue the pros and cons, for example. a method that returns what is actually List<T> , returning it as List<T> or IList<T> or ICollection<T> or IEnumerable<T> . There are some good principles that we can apply to this solution, but there remains an advantage in that, and in the other direction, as far as possible, it can remain useful and as narrow as possible.

However, this is not applicable here. There is no way that Control.FindControl() could return a Label unless it was defined only to return labels. This is not what it is for, it is for returning any type of control, and therefore the result can be just as easily a repeater or grid.

You yourself say SaveViewState , "cast to can be a string type." The answer is that it’s possible. Of course, it can be a string, but it can be object[] or List<string> or Dictionary<string, string> .

If you were the programmer who wrote SaveViewState , how would you define it? You must cover all these possibilities and much more, so you will need to define it as a returning object .

+5
source

The fact that this ID defined in the markup file does not mean at all that the type is known at compile time, worse, there is no way to check it at all, since the markup file is not part of the compilation process.

It is also unlikely that one could do something like this using the string identifier, since C # does not support the concurrent support of return types (you cannot have a method called FindControl that returns both Label and Control ).

The closest thing you could have from this would be to create an IDE to create the FindLabel1 extension FindLabel1 , which will then be used for you, but it will just hack like your code, it does not guarantee anything.

+3
source

Label Label1 = (Label)Grid.FindControl("Label1");

In this example, why FindControl returns an instance of type Control, and we must attribute it to type Label.

You're wrong. The return type of the Control method, but the return type of the instance is Label (otherwise you cannot raise it).

It could return an instance of type Label, since we are passing a valid identifier declared in the markup of the method argument.

Maybe it can. But what you are really asking here is why I need to retell. Since the type of the return method is declared as Control , and this is because there is generally no way to find out your type of control at compile time, when variable types are resolved.

+3
source

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


All Articles