proseidon
proseidon

Reputation: 2305

What's the proper way to handle a variable across multiple methods?

Say I have a List<Objects>. I want to define the list of objects in one method, and use them in several others.

Here's the ways I've come up with and I'm looking for more or the correct way to do it.

  1. You can define List<Objects> in every method that uses it.
    • Pros: It works. No chance of getting the wrong variable.
    • Cons: Code duplication.
  2. You can use a private List<Objects> defined in the class and update it using (ref ListObjects)
    • Pros: I only have to define it once.
    • Cons: I feel like it's messy and bad practice.
  3. You can pass List<Objects> as a parameter to the methods that use it.
    • Pros: Prevents code duplication
    • Cons: Have to make my populate functions return functions, and add parameters to my other methods. Possible conflicts with Events?

So that's what I've come up with. I'm really not sure which to use or if there's a better way to do this. Thoughts?

EDIT: Including some code as requested.

private List<MedicalPlan> medicalPlansList;

This is the list. It is a list that gets information from a database, here:

private void BindMedicalList()
{
   medicalPlansList = new MedicalPlanRepository().RetrieveAll().Where(x => x.Year == year).ToList();
}

Then it's used to find objects in that list, such as

var result =
                    medicalPlansList.FirstOrDefault(
                        c => c.CoverageLevels.Any(p => p.Id == id));

Upvotes: 2

Views: 3236

Answers (4)

Anders Arpi
Anders Arpi

Reputation: 8397

This is, in general, how I'd do it. If you always use the same sequence of functions on a list, consider creating a chained function to handle that. You can also directly pass a function call inside one of the other function calls (as long as it returns a list), but that tends to look messy.

public List<int> DoSomethingWithList(List<int> list)
{
    //do stuff
    return list;
}

public List<int> DoSomethingElseWithList(List<int> list)
{
    //do other stuff
    return list;
}

public void SomeOtherFunction(string[] args)
{
    var list = new List<int>() { 1, 2, 3, 4 }; //create list
    list = DoSomethingWithList(list); //change list
    list = DoSomethingElseWithList(list); //change list further
}

If you are working with an object that has a List<T> field, I'd do like this:

public class MyBigClass
{
    private List<int> myList;
    public MyBigClass()
    {
        //instantiate list in constructor
        myList = new List<int>() { 1, 2, 3, 4 }; 
    }

    public void PublicListAdder(int val)
    {
        myList.Add(val);
    }

    private void PrivateListCleaner()
    {
        //remove all even numbers, just an example
        myList.RemoveAll(x => x % 2 == 0);
    }
}

You rarely need to use ref in C#, because it automatically handles pointers for you. You are (usually) not passing around a struct, you are passing around an object reference (which basically is a pointer).

Upvotes: 2

Diego D
Diego D

Reputation: 8163

Usually a List<T> shouldn't belong to the state of an instance and exposed since it's mutable and you may change the state from the outside otherwise -unless your getter is designed to return a readonly list. Unless your design clearly allow such a possibility when it may occur. My reply doesn't really answer to your question is just a suggestion of good object oriented design. As someone already suggested much better than me you may pass a List back and forth each method and directly modify it.

Upvotes: -1

Jeff
Jeff

Reputation: 14279

In most cases, I would probably go with Anders' answer. Depending on your situation, another way that is worth considering is to write extension methods for List.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static object DoSomething(this List<T> list)
        {
            //do the something with list
        }
    }   
}

And then you can use it like so:

var list = new List<int>();
list.DoSomething();

In that example, list is passed as the parameter to the extension method.

Upvotes: 0

Dan Puzey
Dan Puzey

Reputation: 34198

Your #1 and #2 don't really make sense:

  1. If you define a different list in every method that uses it, then you're using a different list each time. This is not sharing the list; this doesn't work. If you mean "call your method that creates the list from each method that uses it" then the same still applies: you're using a different list each time.
  2. You don't need to use ref ListObjects to update a private member; a private member is just accessed by its name. This isn't bad practice; this is standard object-oriented practice.
  3. Passing all required data into a method as parameters makes the method inherently more reusable as it reduces coupling to the class the method belongs to.

In short: #3 is good practice to an extent, as it increases the reusability of code. However, the use of #2 is fundamentally the reason we have Object-Oriented programming: to save you from repeatedly passing parameters into all your methods. This is exactly what private fields are designed for!

Upvotes: 0

Related Questions