Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why some methods in C# return narrow data types when a wider data type would make more sense?

Tags:

c#

I consider myself as a good mid-level .Net developer, and I’ve gotten a decent understanding of all concepts and terminologies in C# after having worked on it for the last 3+ years. However, there’s this one question I have and I apologize if it looks like a dumb and silly question. What I want to know is why some methods in the Framework Class Library return narrow data types when a wider data type would make more sense, and we have to later cast it to the data type we are interested in. I would like to give the following two examples to support my question:

  1. Label Label1 = (Label)Grid.FindControl("Label1");
    In this example, why is FindControl returning an instance of Control type, and we have to cast it to a Label type. It could have returned an instance of Label type since we are passing a valid ID declared in the markup in the method argument.

  2. protected override object SaveViewState()
    In this example, on object is returned which we have to cast to may be a string type.

I’m sorry once again if my question is confusing. All I want to know is why such scenarios are returning wider types when they could have returned narrow types and it could avoid us an additional step of casting to the type we want.

like image 866
Kevin Watson Avatar asked Dec 05 '22 14:12

Kevin Watson


2 Answers

Firstly, you're a bit turned around, since "wider" is normally used for the less derived types. E.g. Control is wider than Label because the definition covers everything derived from Control, which includes Label and also other things.

As to the actual question. There are times when one can argue pros and cons of e.g. a method that is returning what is actually a List<T> returning it as List<T> or IList<T> or ICollection<T> or IEnumerable<T>. There are some good principles we can apply to that decision, but there remains an advantage in both going as wide as one can remain useful with and going as narrow as one possibly can.

This doesn't apply here though. There is no way that Control.FindControl() could return Label unless it was defined to only ever return labels. That's not what it's for, it's for returning any type of control, and so the result could just as easily be a repeater or a grid.

You yourself say of SaveViewState, "cast to may be a string type." The answer is in that "maybe". Sure it maybe a string, but it maybe an object[] or a List<string> or a Dictionary<string, string>.

If it was you who was the programmer who wrote SaveViewState, how would you define it? You have to cover all those possibilities and more, so you'd have to define it as returning object.

like image 140
Jon Hanna Avatar answered Dec 10 '22 11:12

Jon Hanna


This because when you design a framework you need to operate on as general level as it possible, or on abstract level, if you wish. Returning most possible base class, in this case, it creates an abstraction that can support for almost anything. 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 retrieve a control from the Grid. The caller knows what is it exactly, so casts to the known type.

If I, like a framework designer, would like to make special methods for Label, TextBox, Calendar, I would need to add one method per type. I think you would agree, that it's simply unthinkable from the framework designer point of view. From the point of view of a developer who should design generic infrastructure for other developers.

like image 40
Tigran Avatar answered Dec 10 '22 10:12

Tigran