如何使用字符串输入访问现有对象(将字符串输入转换为对象名称)
How to get access to existing objects with string input (Convert string input to objectname)
我正在创建很多名为: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 那么我必须重复很多代码,这会降低这个东西的可读性,因为我必须用不同的方式调用 相同的函数 对象。
这听起来像是一个经典的策略模式问题Strategy Design Pattern
代码如下:
//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在.
中给出了一个例子
不过,直接 回答您的问题,因为它适用于 Java,如下所示。虽然 C# 的代码会有所不同,但可用于此目的的语言功能,即 反射,在 C# 中也可用。
如果 Obj1
、Obj2
等在 class 中声明为静态或实例字段,您可以使用反射通过它们的名称获取它们的值(参见 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#).
静态字段
class Something {
static Object obj1 = new Object();
static Object obj2 = new Object();
// etc.
}
(我冒昧地以小写字母开头字段名称,因为这是 Java 中公认的做法。)
在这种情况下,您可以使用以下代码通过名称获取变量的值(您需要导入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.
}
对于实例字段,您可以使用几乎完全相同的方式进行操作,您只需要将 class 的实例传递给 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);
局部变量
在这种情况下,您可能不走运。同样,请参阅以下链接:Java, C#.
答案是……不要。请改用数组。这正是他们的目的。
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();
我正在创建很多名为: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 那么我必须重复很多代码,这会降低这个东西的可读性,因为我必须用不同的方式调用 相同的函数 对象。
这听起来像是一个经典的策略模式问题Strategy Design Pattern
代码如下:
//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在
不过,直接 回答您的问题,因为它适用于 Java,如下所示。虽然 C# 的代码会有所不同,但可用于此目的的语言功能,即 反射,在 C# 中也可用。
如果 Obj1
、Obj2
等在 class 中声明为静态或实例字段,您可以使用反射通过它们的名称获取它们的值(参见 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#).
静态字段
class Something {
static Object obj1 = new Object();
static Object obj2 = new Object();
// etc.
}
(我冒昧地以小写字母开头字段名称,因为这是 Java 中公认的做法。)
在这种情况下,您可以使用以下代码通过名称获取变量的值(您需要导入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.
}
对于实例字段,您可以使用几乎完全相同的方式进行操作,您只需要将 class 的实例传递给 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);
局部变量
在这种情况下,您可能不走运。同样,请参阅以下链接:Java, C#.
答案是……不要。请改用数组。这正是他们的目的。
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();