Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Modifying elements of an ArrayList- Any help please?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Modifying elements of an ArrayList- Any help please?

    This might be a general C# question. But any help or guidance is highly appreciated.
    I am using a ArrayList of struc “Osto”. I Unbox the values as I read from the ArrayList “List”. Struct “Osto” contains IOrders like Oe1, Oe2, Os1, Os2 and Ol1 along with other data types.
    Now I like to change one element (Oe1) from a particular element (for instance say 2nd element) of the Arraylist “List”. I get an error message “Cannot modify the result of an unboxing conversation” near If-statement.
    Do I have to remove the i th element, reconstruct it and then add it back to the “List”? Any simpler way of modifying just the particular inner element(Oe1)?
    Many thanks in advance.


    My Code:
    // struc containing info of stops, limits, IOrders of Positions that opened at an instance
    privatestruct Osto {publicdouble op;publicdouble st;public DateTime tm;public IOrder oe1;public IOrder oe2;public IOrder os1;public IOrder os2;public IOrder ot1;}
    // Arraylist to store the data of Resistance, Support and Orders
    private ArrayList Shortord = new ArrayList();

    privateint Gono(IOrder Or, ArrayList List){
    bool B1;
    for (int i=0;i<List.Count;++i){
    B1=(Or.Token==(((Osto)List[i]).oe1).Token);// OK
    if(B1){
    ((Osto)List[i]).oe1=Or;// ERROR! I am assigning IOrder Or to i th element of List which is a struc of type Osto.
    return i;
    }

    }
    return0;
    }

    #2
    malmaa, unfortunately this is beyond our support level. Maybe some community members can help you out.
    AustinNinjaTrader Customer Service

    Comment


      #3
      Malmaa,

      for such pattern I don't have experiences with array list, because I use generic list in these cases. I think the following should work:

      private List<Osto> Shortord = new List<Osto>();
      ...
      Shortord[i].oe1 = newvalue;

      Regards
      Ralph

      Comment


        #4
        Thanks a bunch Ralph.

        A very simple modification in my code. No casting, no unboxing. I understand, if there are different types of objects in the list go for "ArrayList", if all the elements are of similar type go for generic "List".
        Appears code is simplesr and works very much to my needs.

        Cheers,

        Comment


          #5
          Hi malmaa,

          according to the MS docs, boxing/unboxing is done when applying value types to ArrayList, and your struct Osto is a value type. I guess in that case you try to apply your new value to a copy of what is originally contained in the ArrayList, and therefore your modification doesn't make it back into the ArrayList. Your original approach may work perhaps if you use a class Osto instead of a struct. Classes are reference types and don't need to be boxed.

          However, according to your explanation in your last post I believe too the generic list is the better choice for your application.

          Regards
          Ralph

          Comment


            #6
            Ralph,
            Are you really able to use the format Shortord[i].oe1 = newvalue;
            because my statement containing
            Shortord[i].os2 = ExitShortStop(0,true,10000,Brchs,((Shortord[i]).oe2).Name + "S",((Shortord[i]).oe2).Name);
            Gives an error message”Cannot modify the return value of 'System.Collections.Generic.List<NinjaTrader.Strat egy.Resislis.Osto>.this[int]' because it is not a variable”CS1612.
            It appears to me that any object within a list can not be directly modified as a variable. That is way I rebuilt the complete element and then assigned as
            Shortord[i]= Ortmp; I tried with class instead of struc but since we do not know the number of elements in the List, initialization of number of class objects is complicated. If you are sure that you have used your above statement? Request you to reply so that I can do some research.
            Regards,

            Comment


              #7
              Hi Malmaa,

              Shortord[i].os2 = ExitShortStop(...); is possible in C/C++.

              With C# you can access only instances of class Osto directly with your generic list List<Osto>. To reach the class members of Osto you need to implement an additional step:
              Osto o = Shortord[i];
              o.os2 = ExitShortStop(...);
              Since we are dealing with class references, the modifications in o.os2 are reflected in Shortord[i] also.

              ... but since we do not know the number of elements in the List ...
              I don't understand what that means? (a list does not have a fixed size).

              Regards
              Ralph

              Comment


                #8
                Thank you Ralph for your quick reply. I got the method of changing the values of List containing class objects. I problem is in initialization of the objects in the list.
                To create an instance of a class in general, we use
                Osto Var = new Osto(); (where Var is an instance of the class not a list)

                Since we are using a List do we have to use the same statement for every element of the list like
                Osto Shortord[i] = new Osto();-------------------(1)

                Right now I create a local variable
                Osto Local; -----------------(2)
                // assign values for the “Local”
                Shortord.Add(Local);

                My question is how to declare the List containing class objects? Follow (1) or (2)?
                Thank you so much for your help.
                Regards,

                Comment


                  #9
                  (1) is possible only if you modify/override an existing list element. With indexed access you can't add new elements to the list (you get a runtime index violation).

                  For initialisation purpose you have to go with (2). If your initialisation routine is kind of generic, you could use a loop to add a certain number of elements.

                  Alternatively you could consider a late list initialisaton, means to add a new element in the moment your code requires to get a new Osto object.

                  Regards
                  Ralph

                  Comment


                    #10
                    Thanks Ralph for your help. I think your late initialization makes more sense for my routine and I have two more options .
                    Osto Local;
                    Shortord.Add(new Osto( Local));----------(3)
                    Shortord.Add(new Osto( individual values));--------(4)
                    At a point you said that class are reference objects, so if I use option (3) constructing List elements with same variable ”Local”, will all the elements refer to same address? (i.e changing one element changes all other elements of the List) If that is the case I might have to go for option(4) where I construct the Osto with individual values rather than a variable containing them.
                    Regards,

                    Comment


                      #11
                      Osto Local;
                      Shortord.Add(new Osto( Local));----------(3)


                      I guess there is something wrong with your code because you implemented recursion: Your instance creation new Osto() takes an instance Local of type Osto as an argument.
                      However, if you are doing the following then all list elements would point to the same Osto() instance:

                      Osto Local = new Osto(...);
                      for (int i = 0; i < 10; i++)
                      Shortord.Add(Local);

                      To create individual Osto objects you would need to implement something like this:

                      for (int i = 0; i < 10; i++)
                      Shortord.Add(new Osto(...));

                      or this:

                      Osto Local;
                      for (int i = 0; i < 10; i++)
                      {
                      Local = new Osto(...);
                      Shortord.Add(Local);
                      }

                      Regards
                      Ralph

                      Comment


                        #12
                        Dear Ralph,
                        Fantastic information!
                        Appreciate your patience and expertise.
                        You have explained every thing I need to know about List and Class. Just out of my anxiety, do we have to “Destroy” (from memory) the no-longer-required deleted class objects from the List.
                        Thank you so much for your help.
                        Regards

                        Comment


                          #13
                          Thanks for your kind words, Malmaa.

                          As soon as you removed the no longer needed class instances from the list and there are no other references to these instances, you just can forget them without anxiety. The garbage collector takes all orphans and cleans up the memory. That also means that you need to take care about closing critical resources (i.e. file streams). You should use a method named Dispose() for this purpose. You can find a hint in the NT docs about Dispose() because NT uses this method when shutting down an indicator.

                          Regards
                          Ralph

                          Comment


                            #14
                            I'm trying to understand how to create a list inside of NT.

                            Using the following reference:
                            Create a new List, add elements to it, and loop over its elements with for and foreach.


                            Basically, to create a generic list to store values in, what needs to go in the "Variables" block, and what needs to go in the "Initialize" block?

                            Comment

                            Latest Posts

                            Collapse

                            Topics Statistics Last Post
                            Started by kujista, Today, 05:44 AM
                            0 responses
                            6 views
                            0 likes
                            Last Post kujista
                            by kujista
                             
                            Started by ZenCortexCLICK, Today, 04:58 AM
                            0 responses
                            8 views
                            0 likes
                            Last Post ZenCortexCLICK  
                            Started by sidlercom80, 10-28-2023, 08:49 AM
                            172 responses
                            2,281 views
                            0 likes
                            Last Post sidlercom80  
                            Started by Irukandji, Yesterday, 02:53 AM
                            2 responses
                            18 views
                            0 likes
                            Last Post Irukandji  
                            Started by adeelshahzad, Today, 03:54 AM
                            0 responses
                            11 views
                            0 likes
                            Last Post adeelshahzad  
                            Working...
                            X