如何在变量上使用索引

时间:2017-11-14 00:08:15

标签: c#

我有一个列表,我目前按以下方式添加项目:

public GameObject object1 = new GameObject("Example Data");
public GameObject object2 = new GameObject("Example Data");
public GameObject object3 = new GameObject("Example Data");
public GameObject object4 = new GameObject("Example Data");
public GameObject object5 = new GameObject("Example Data");
public GameObject object6 = new GameObject("Example Data");
public GameObject object7 = new GameObject("Example Data");
public GameObject object8 = new GameObject("Example Data");
public GameObject object9 = new GameObject("Example Data");
public GameObject object10 = new GameObject("Example Data");
List<GameObject> Objects = new List<GameObject>();

Objects.Add(object1);
Objects.Add(object2);
Objects.Add(object3);
Objects.Add(object4);
Objects.Add(object5);
Objects.Add(object6);
Objects.Add(object7);
Objects.Add(object8);
Objects.Add(object9);
Objects.Add(object10);

我如何使用foreach在C#中执行此操作?我试过类似下面的例子,但我无法让它起作用:

foreach (var number in Enumerable.Range(1, 10))
{
    Objects.Add("object" + [number]);
}

4 个答案:

答案 0 :(得分:4)

没有简单的方法将字符串转换为变量名称,但根据您的尝试,您可以完全摆脱object1变量:

// Personally I'd use a simple for loop instead of this 
foreach (var number in Enumerable.Range(1, 10))
{
    Objects.Add(new GameObject("Example Data"));
}

编辑:使用1..10的范围会让你在某个地方迷惑。在C#中,一切都是0。只是吮吸它,不要试图假装它不是......

答案 1 :(得分:2)

我会推荐一个for循环。循环i次并创建一个新对象并将其添加到列表中。

for(int i = 0; i < 10; i++)
{
    GameObject ob = new GameObject("Example Data " + i);
    Objects.Add(ob);
}

答案 2 :(得分:1)

为了使用动态生成的名称读取私有字段,您需要编写一个特殊函数来通过Reflection读取它。以下是我将如何编写这样的函数:

public static object GetFieldValue(this object input, string name)
{
    return input
        .GetType()
        .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
        .ToList()
        .Where(f => f.Name == name)
        .Single()
        .GetValue(input);
}

然后您可以像这样使用它:

for (int i = 1; i <= 10; i++)
{
    string fieldName = "object" + i.ToString();
    var o = this.GetFieldValue(fieldName);
    objects.Add(o);
}

话虽如此,这不是一个好主意。事实上,这是一个 真的 奇怪的事情。您处理此问题的正常方法是完全省略objectX个变量;只需将每个实例存储在列表中。

List<GameObject> Objects = new List<GameObject>();
for (int i=0; i<10; i++)
{
    Objects.Add(new GameObject("Example data"));
}

如果你需要从列表中取出其中一个实例,只需按索引引用它(尽管你可能不得不减去1,因为它是从0开始的):

var object1 = Objects[0];

另一种处理它的方法,特别是如果每​​个实例在某种程度上都是唯一的,那就是使用字典:

Dictionary<string, GameObject> objects = new Dictionary<string, GameObject>();
objects["Player"] = new GameObject("I am a player");
objects["Enemy"] = new GameObject("I am an enemy");
objects["NPC"] = new GameObject("I am a hapless bystander");

然后,您可以按名称访问每个单独的对象,或者如果需要,您可以迭代所有这些对象,例如:如果您需要使用一个对象,可以使用

objects["Player"].Dispose();
objects.Remove("Player");

如果您需要一次处理所有事情(例如游戏结束):

foreach (var o in objects) o.Dispose();
objects.Clear();

通常情况下,如果您发现自己将数字放在变量名称中,则可能在设计中犯了错误。将它们放入数组,列表或其他旨在包含多个实例的数据结构中几乎总是更好。

答案 3 :(得分:1)

可以通过反思。

public class MyClass
{
    public GameObject object1 = new GameObject("g1");
    public GameObject object2 = new GameObject("g2");
    public GameObject object3 = new GameObject("g3");

    public void AddObject()
    {
        List<GameObject> list = new List<GameObject>();

        for (int i = 1; i <= 3; i++)
        {
            var o = this.GetType().GetField($"object{i}").GetValue(this) as GameObject;    
            list.Add(o);
        }           
    }
}