1

I have a bit of a rudimentary question. I have a total of two classes.

I have a few methods inside one class. The skeleton structure is so:

First class is called EvenBetterValueList (public):

public override void AppendAdditionalMenuItems(ToolStripDropDown menu){
    // Stuff
}

private void Menu_MyCustomItemClicked(object sender, EventArgs e){
    // Stuff
}

protected override void SolveInstance(IGH_DataAccess DA){
    // firstList and secondList list<string> declaration
    ValueList newList = new ValueList(firstList, secondList);
}

Second class is called ValueList (as you can tell in my SolveInstance method. This too is public):

The skeleton is:

    private List<string> _firstList = new List<string>();
    private List<string> _secondList = new List<string>();

    public List<string> FirstList 
    {
        get { return _firstList; }
    }

    public List<string> SecondList
    {
        get { return _secondList; }
    }

    public ValueList(List<string> firstList, List<string> secondList) {
        _firstList.Clear();
        _secondList.Clear();

        // Add vars to global vars

        _firstList.AddRange(firstList);
        _secondList.AddRange(secondList);
    }

My question is, in SolveInstance of the first class EvenBetterValueList, I am able to use the new instance newList that I've declared. However, I am unable to use this instance in the other methods, like AppendAdditionalMenuItems() or Menu_MyCustomItemClicked().

I would like to access newList inside those two methods, and call things like newList.FirstList[index] or newList.SecondList[index].

The way this abstract class works is that it always called SolveInstance() before anything, I feel this information is quite important.

Is this a scope issue? How do I solve it?

6
  • Please use AddRange if available, rather than calling Add in a loop... Or one of the many other available ways of combining lists... Commented Jan 29, 2014 at 15:51
  • That's not the question.. But do you mean _firstList.AddRange(..) versus _firstList.Add(..)? What's the difference? Commented Jan 29, 2014 at 15:52
  • When you add something to a collection, the collection's internal array may have to enlarge to fit the new element. If you do that in a loop, it may happen N times. If you do AddRange, it happens once, and you don't need a loop. You probably don't even need the ValueList class, since it doesn't add anything that normal Lists can't do with Linq. Commented Jan 29, 2014 at 15:53
  • I made the ValueList class so it's easier to read for future devs, and there are additional methods below. How do you use .AddRange(..) without a for-loop? Commented Jan 29, 2014 at 15:58
  • 1
    _firstList.AddRange(firstList);, for instance. It adds all the values in firstList to _firstList, but you don't have to think about it. If it matters that the elements alternate from the two lists, you could try Linq's aggregate. Commented Jan 29, 2014 at 16:03

2 Answers 2

1

One solution may be to add a private variable in the class with class scope. Add the line:

ValueList _valueList;

Just outside of the method and use that one instead of newList within your methods.

Read more about scopes http://msdn.microsoft.com/en-us/library/aa691132(v=vs.71).aspx

Sign up to request clarification or add additional context in comments.

2 Comments

Hey Lars. When I declare my _valueList using: ValueList _valueList = new ValueList(firstList, secondList);, I get this warning: puu.sh/6CHP1/361f7a8552.png I also included the SolveInstance() where I create the new instance.
It is becouse you create a new instance in your method right now. On the row where you say ValueList _valueList = new ValueList... you are not using the class scoped variable. You are creating a new variable in the method. Remove the class name infront of the local variable will make the code use the class variable instead.
1

The problem that you're having is that newList is defined only within your SolveInstance method, meaning that you were correct about it being a scoping issue. Declare it as a private field, and it will be available. I'd also consider changing SolveInstance into the constructor if the method is indeed always called before anything else.

4 Comments

Do you mean declaring SolveInstance() as a private field? There is no need to turn SolveInstance() into a constructor as public class EvenBetterValueList : GH_Component does all the work of determining what gets executed first.
If as you stated above SolveInstance() is always called before any other method, why force users to remember that? That's what constructors are for. Including more detail in your comments that isn't visible in your post to invalidate comments, criticism, and advice helps no one, particularly you. If the domain of your problem is important, leaving it out will not get you an answer you can use.
It's actually an abstract class I'm using - I'm coding up an application for Grasshopper 3D. Not much I can do inside those confines =P.
Hey Magus.. I know you answered first, but Lars provided the code snippet, so I accepted his answer. No hard feelings?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.