1

I am creating a lot of objects called: Obj1, Obj2.... ObjX

Object Obj1 = new Object();
Object Obj2 = new Object();
Object ObjX = new Object();

Now I am having a function where I want to get access to one of this objects.

public void useObject(int objectNumber) {
     String objectName = "Obj" + objectNumber;
     objectName.doAnythingWithThisObject();
     }

Is something like that possible in C# or Java? I don't want to use something like:

switch(objectNumber) {
      case 1: 
        Obj1.doThis();
       break;
      case 2: 
        Obj2.doThis();
       break;

If I would use switch/if-else then I have to repeat a lot of code which make this thing less readable, because I have to call the same function with different objects.

basti12354
  • 2,490
  • 4
  • 24
  • 43
  • At what scope are `Obj1`, `Obj2` etc. declared? Are they static, instance or local variables? – TerraPass Mar 28 '16 at 16:01
  • 1
    By the way, why not just use an array or another collection to store your objects? – TerraPass Mar 28 '16 at 16:02
  • 1
    This isn't PHP where you can reference a variable just by putting its name in a string. You have your `Object` class store a `int ObjectNumer;` which is only set in the constructor by using a `static int objectCount;` field which gets incremented on each construction of such an object. You can then save a reference of all `Object` objects somewhere sothat you can later pull out the right object according to the `objectNumber`. (i.e., singleton method) – Maximilian Gerhardt Mar 28 '16 at 16:03
  • @TerraPass: Objects are instances – basti12354 Mar 28 '16 at 16:06
  • This would be solved instantly with an array. You don't need multiple references like you're using above. obj[i] is so much cleaner than trying to map to obj1, obj2, etc. – ManoDestra Mar 28 '16 at 16:58

4 Answers4

1

This sounds like a classic Strategy pattern problem Strategy Design Pattern

Eminem
  • 7,206
  • 15
  • 53
  • 95
1

Here's the code:

    //Declare this in the class so that it can be called by any method
static Object[] array = new Object[4];
public static void main()
{
    //Use this to initialize it
    Object[] array = new Object[4];
    for(int i=0;i<4;i++)
    {
        array[i] = new Object();
    }
    //You can now easily call it
    useObject(0);
    useObject(1);
    useObject(2);
    useObject(3);
}

//Your numbers may be off by 1 because we are using an array but that is easily adjusted
public static void useObject(int objectNumber)
{
    array[objectNumber].doAnythingWithThisObject();
}
T.R.Rohith
  • 11
  • 3
1

The actual answer is: you shouldn't, generally speaking, access your variables, using strings at runtime. Cases where this is actually appropriate are few and far between and your example, simplified though it may be for illustration purposes, is not a good match for it.

Instead, why don't you simply use a collection or an array to store your objects? @T.R.Rohith gives an example in their answer.

Still, the direct answer to your question, as it applies to Java, is given below. While the code would be different for C#, the language feature, which can be used for this purpose, namely, reflection, is available in C# as well.


If Obj1, Obj2 etc. are declared as static or instance fields in a class, you can get their values by their names using reflection (see relevant docs for Java). If they are local to a method, there is no simple way to do so (see these questions: for Java, for C#).

Static fields

class Something {
    static Object obj1 = new Object();
    static Object obj2 = new Object();
    // etc.
}

(I've taken the liberty of starting field names with lowercase letters, as it the accepted practice in Java.)

In this case you can get the value of the variable by its name using the following code (you need to import java.lang.reflect.Field):

// Get field, named obj1, from class Something.
Field f = Something.class.getDeclaredField("obj1");
// This line allows you access the value of an inaccessible (non-public) field.
f.setAccessible(true);
// Assigning the value of the field, named obj1, to obj.
// You may want to cast to a more concrete type, if you know exactly what is stored in obj1.
// The parameter for get() is ignored for static fields, so simply pass null.
Object obj = f.get(null);

// Now you can do whatever you want with obj, 
// which refers to the same object as static field obj1 of Something.
System.out.println(obj);

Instance fields

class Something {
    Object obj1 = new Object();
    Object obj2 = new Object();
    // etc.
}

You can do it in almost exactly the same way for instance fields, you just need an instance of the class to pass to f.get(). So, for the sake of example, let's assume we have an instance of class Something, called sth.

// Let's say this is an instance of our class
Something sth = new Something();
// ...

// Get field, named obj1, from class Something.
Field f = Something.class.getDeclaredField("obj1");
// This line allows you access the value of an inaccessible (non-public) field.
f.setAccessible(true);
// Assigning the value of the field, named obj1, to obj.
// You may want to cast to a more concrete type, if you know exactly what is stored in obj1.
// The parameter for get() is the instance of Something, 
// for which you want to retrieve the value of an instance field, named obj1.
Object obj = f.get(sth);

// Now you can do whatever you want with obj,
// which refers to the same object as instance field obj1 of sth.
System.out.println(obj);

Local variables

You are probably out of luck in this case. Again, see the following links: Java, C#.

Community
  • 1
  • 1
TerraPass
  • 1,562
  • 11
  • 21
1

The answer is... don't. Use an array instead. This is exactly what they're for.

ObjectType[] objectArray = new ObjectType[10]; // Or as many as required.
for (int i = 0; i < objectArray.length; i++) {
    objectArray[i] = new ObjectType(); // Or whatever constructor you need.
}

// Then access an individual object like this...
ObjectType obj = objectArray[4];

// Or...
objectArray[5].someMethod();
ManoDestra
  • 6,325
  • 6
  • 26
  • 50