Using Objects as Parameters in C#

Hands up, how many of you create monster functions and methods in your projects? And no, I'm not on about routines that are a million lines long, what did you think I meant? I'm actually talking about those functions that have signatures that could easily span over two lines if word wrap were turned on.

In Today's Nuts & Bolts post, we look at why functions like this cause a problem, and what you can do to keep yourself from getting into these kinds of messes.

It's not about any special thing that is specific to .NET but a general programming technique that makes your code easier to read, and begins to help you understand IoC (Inversion of Control)

Starting with the Problem

We've all seen them, those functions & methods that seem to go on forever:

public Class1()
{
  public myMethod(int age, string name, string surname, int yearBorn, int weight, float xlocation, float ylocation ......)
  {
  }
}

You can see that even my example is hard to read, and it's not even in a full blown project with many other lines of code. Imagine, trying to navigate a source file that had masses and masses of function prototypes like this; I think finding a needle in a haystack would be much easier.

Why is This Bad?

Well we've already seen one reason why coding like this is bad; readability.  You might be okay with it when you’re writing this code, but what happens when you come back six months later? Imagine you’re the maintenance programmer who has to take over looking after this thing, and answering inbound support calls from customers out in the field using the software. These are just a couple of reasons to consider. There are many other reasons too.

What if during development your specs get changed, and you suddenly find that you need to add a parameter to pass in a value of how much food is eaten in a month. What about if you need to rename a parameter?

Going one step further, what about optional parameters? You know the ones where you can add a default value:

public myMethod(int age = 20 ......)
{
}

Imagine if you had to update that “20” to a “40” in all instances.

Very quickly this becomes something that's very likely going to lead to mistakes being made in your project, and if you’re under any doubt about how easy it is to miss a parameter like that amongst masses of other code, take some advice from me, it's stupidly easy.

I like many professional developers have been there and made these mistakes, and it's no fun spending a Sunday afternoon trying to hunt down something you just can't quite put your finger on.

How do You Solve This?

As it happens, it is quite easy to solve this. Instead of adding all your parameters in one go, use an object.

Now before we go any further, notice I'm using the term 'Object' here.  To me this will generally mean a class, some people however prefer to use structs, some prefer generic objects, it really doesn't matter what you use, the principle is still the same, and I have no desire to get into a religious war over which type is best.

One thing I will say is each type has its advantages and its disadvantages, and if any of you have ever read my posts in Lidnug, then you'll know already that I'm a firm believer in looking at all your options and using the correct tool for the job.

Moving on.

Let's take our example above:

public myMethod(int age, string name, string surname, int yearBorn, int weight, float xlocation, float ylocation ......)

We can see that we have at least seven items of data we’re using, so let's flesh this out into a class.

public class myMethodParams
{
  public int age { get; set;}
  public string name { get; set;}
  public string surname { get; set;}
  public int yearBorn { get; set;}
  public int weight { get; set;}
  public float xlocation { get; set;}
  public float ylocation { get; set;}
}

And then change our function signature:

public void myFunction(myMethodParams theParams)
{
}

Immediately it looks much more readable.

But now we have other benefits too.

Because a class is being used, you can add methods that can act just like parameters, and in fact this is one of the underlying concepts of object orientated programming, making objects self aware and expose only what they need to.

Encapsulation is a very powerful thing when used correctly, to 'myMethod' all it sees is what it needs to see, nothing more.

What about Defaults? Well, you can easily add an extra field, and then some code to initialize it to a known value:

public class myMethodParams
{
  public int age { get; set; }
  public string name { get; set; }
  public string surname { get; set; }
  public int yearBorn { get; set; }
  public int weight { get; set; }
  public float xlocation { get; set; }
  public float ylocation { get; set; }
 
  public myMethodParams()
  {
    age = 20;
  }
}

If you never set 'age' to a value, you can guarantee that it'll be set to '20' and not have to worry about it.

Is This Just a Quick Tutorial on OOP?

If you've done any formal programming language training in the past ten years then this stuff will be (or should be) second nature to you. If you’ve not, then this might be new to you. Regardless, having a refresher never really hurts anyone.

Ask yourself this question though:

How often do you pass full classes/objects as parameters to regular methods?

I'm willing to bet not very often. In fact I'll even go so far as to say that most of you probably do something like this most of the time:

public class HomeController : Controller
{
  public HomeController(myDataObject theObject)
  {
  }
 
  public ActionResult Index()
  {
    return View();
  }
}

And leave it at that.

Well what your actually practicing here is 'IoC', which means 'Inversion of control'. Essentially what you’re doing is your passing an object that's responsible for its own state, has its own processing methods and likely quite a chunk of other functionality.

Why 'Inversion'?

Well it's because you’re giving the data object the control of its lifetime within the 'Controller class' it's used in above, rather than the traditional way of having the controller class 'new' a copy of the data object, and control it.

You’re taking control away from the class that's using the data object, and inverting that control, so that the data object is in charge.

In Summary

The point I'm trying to make here though, is why only restrict yourselves to the scenario above?

ASP.NET MVC enforces this paradigm by default, but there's absolutely no reason why you can't make your own code/projects easier to manage and easier to read by adopting similar methods.

If you have any ideas for posts for this series, please reach out to me on twitter '@shawty_ds' or come and find me in the Linked .NET users group (Lidnug) on the Linked-In social network. Until next time, code happy.



Related Articles

Comments

  • named parameters

    Posted by Yves on 06/12/2014 11:47am

    Do you know named parameters? I have just overlooked the article and named parameters may solve the issue you describe. If not, I need to read it in detail...

    Reply
  • Bad idea

    Posted by Karsten on 06/11/2014 08:52am

    it creates dependencies on all source files and classes. One change and a lot of work. Try this at home - NOT at work...

    Reply
  • Really bad ass idea

    Posted by Karsten on 06/10/2014 02:02am

    if objects and classes are parameters to others classes it creates dependencies on interfaces. If the class interfaces are changed - a lot of code is to be maintained. Stay native - big interfaces are an architectual problem. One task = one class. If code is shared between projects or companies it will BREAK AND KILL.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Available On-Demand Today's changing workforce dynamics, economic challenges, and technological advances are placing immense pressure on business leaders to turn their focus on people – their most valuable asset – in order to remain competitive. Research shows that a significant number of new employees quit within one year of taking a new job*. Whether it's through a merger and acquisition, or standard hiring process, like any first impression, early experiences shape their opinions of their new …

  • Do you know where your data is? Consumer cloud-based file sharing services store your sensitive company data on servers outside of your control, outside of your policy and regulatory guidelines – maybe even outside your country – and not managed by you. The potential for data leakage, security breaches, and harm to your business is enormous. Download this white paper to learn about file sync and share alternatives that allow you to manage and protect your sensitive data while integrating and …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds