Tono Nam
Tono Nam

Reputation: 36070

Initialize several global variables using an array

Lets say I have the class

class Foo
{
    public int Value { get; set; }
}

And I have the global variables:

public static Foo A1 { get; set; }
public static Foo A2 { get; set; }
public static Foo A3 { get; set; }
public static Foo A4 { get; set; }
// etc... more

The following code will not set the value of those global variables:

var elementsToSet = new Foo[]{A1,A2,A3,A4}; 

for (var i = 0; i < elementsToSet.Length; i++)            
       elementsToSet[i] = new Foo {Value = i};

In other words A1 == null is true :(

I am trying to initialize A1, A2, etc not the array


how can I prevent having to do:

A1 = new Foo { Value = 1 };
A2 = new Foo { Value = 2 };
A3 = new Foo { Value = 3 };
A4 = new Foo { Value = 4 };
// etc...

PS

I know I can have an array as my global variable instead of several. I am just asking this question to learn. I have the reference of each variable. I want to set a new variable of the same type at that address.

Also

If Foo will have been a struct instead of a reference type (class) this will work no?

Upvotes: 3

Views: 151

Answers (2)

Lightman
Lightman

Reputation: 1265

how can I prevent having to do

The idea is to write a method that will:

  1. create a new object for a parameter passed by reference
  2. assign parameter with a newly created object
  3. add object to some collection

This can be implemented in a generic class:

Public Class Builder(Of ItemType)

    Dim Constructor As Func(Of Integer, ItemType)
    Dim Queue As New Queue(Of ItemType)

    Public Sub New(Constructor As Func(Of Integer, ItemType))
        Me.Constructor = Constructor
    End Sub

    Public Function Build(ByRef Item As ItemType) As Builder(Of ItemType)
        Item = Constructor(Queue.Count)
        Queue.Enqueue(Item)
        Return Me
    End Function

    Public Function Items() As IEnumerable(Of ItemType)
        Return Queue
    End Function
End Class

Usage:

Dim Foos = New Builder(Of Foo)(Function(Index) New Foo With {.Value = Index + 1}).
    Build(A1).Build(A2).Build(A3).Build(A4).
    Items

Comments:

  1. Builder uses a Constructor delegate to create each object. Constructor delegate is passed into Builder constructor.
  2. Build function behaves as stated above and returns Builder to chain calls
  3. Items function returns an enumeration of created items
  4. Builder can be used for any class, not only Foo

Upvotes: 0

Jashaszun
Jashaszun

Reputation: 9270

The reason is that your array elementsToSet at first contains four instances of null (because A1, A2, ... A4 are all null originally). Then when you set each of elementsToSet[i] to a new Foo(...) the elements in the array are set, but none of the elements are references to your A1 ... A4 Foos.

Really, the best ways to do this are

  1. Initialize each Foo, one per line. This can get annoying if you have a lot of them.
  2. Have your global variables be in an array, and then loop through and initialize.
  3. Use reflection (the worst idea).

Edit for the question's edit: No, your original code will still not work if Foo is a struct instead of a class, because then setting the elementsToSet[i], even when elementsToSet is initialized with A1 ... A4, will still just set the elements in the array. Even more so, the original A1 ... A4 are not being set through the array.

Upvotes: 1

Related Questions