1

我正在创建很多对象,称为:Obj1,Obj2.... ObjX

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

现在我有一个函数,我想访问其中一个对象。

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

在 C# 或 Java 中是否可能出现类似的情况?我不想使用类似的东西:

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

如果我要使用 switch/if-else,那么我必须重复很多代码,这会降低它的可读性,因为我必须用不同的对象调用相同的函数。

4

4 回答 4

1

这听起来像是一个经典的策略模式问题策略设计模式

于 2016-03-28T16:00:44.230 回答
1

这是代码:

    //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();
}
于 2016-03-28T16:18:36.843 回答
1

实际的答案是:一般来说,您不应该在运行时使用字符串来访问您的变量。这实际上是合适的情况很少而且相距甚远,您的示例虽然可能是为了说明目的而进行了简化,但并不适合它。

相反,您为什么不简单地使用集合或数组来存储您的对象?@TRRohith 在他们的回答中举了一个例子。

不过,下面给出了您的问题的直接答案,因为它适用于 Java。虽然 C# 的代码会有所不同,但可用于此目的的语言功能,即反射,在 C# 中也可用。


如果Obj1Obj2被声明为类中的静态或实例字段,您可以使用反射通过它们的名称获取它们的值(参见Java 的相关文档)。如果它们是方法的本地,则没有简单的方法可以这样做(请参阅这些问题:对于 Java对于 C#)。

静态字段

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

(我冒昧地以小写字母开头字段名称,因为它是 Java 中公认的做法。)

在这种情况下,您可以使用以下代码通过其名称获取变量的值(您需要 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);

实例字段

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

对于实例字段,您可以以几乎完全相同的方式执行此操作,您只需要将类的实例传递给f.get(). 因此,为了举例,让我们假设我们有一个 class 的实例Something,称为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);

局部变量

在这种情况下,您可能不走运。同样,请参阅以下链接:JavaC#

于 2016-03-28T16:56:20.813 回答
1

答案是……不要。请改用数组。这正是他们的目的。

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();
于 2016-03-28T17:03:36.663 回答