2017-10-09 33 views
2

我有一个所谓访问独特的阵列的名字

public int[] box1 = {1, 0, 2}; 
public int[] box2 = {3, 1, 0}; 
public int[] box3 = {2, 3, 1}; 

什么,我需要做的唯一的数组名被动态地访问他们,并从它返回一个随机元素,使用类似的一组整数数组这 -

foo="box"+2[random int]; 

其中foo是我的,包括“盒子”的前缀字符串温度,增加我想“盒子”的数量,正从“BOX2”一个随机元素。 (例如:foo = 3)

如果我通过字符串方法执行此操作,它会创建正确的nomanclature,但它只是一个字符串,我无法使用它实际在脚本中以实际的类/数组元素的形式访问它们,将它们传递给别的东西。

我该怎么做呢?几个小时阅读手册,尝试列表,但我认为我没有做正确的事情。谢谢!

+1

您正在寻找'Dictionary'。 – Programmer

+1

不是'Dictionary','Lookup' –

+1

不是''Dictionary''或''Lookup'',而是一个带有''indexer''的自定义类 –

回答

3

就坏了你真正想要什么做,你会看到它是多么容易。就像我在评论部分提到Dictionary一样,您仍然需要其他两个C#功能来完成确切的语法。

你希望能够做到这一点:

foo="box"+2[random int]; 

这是,与此相同:

int valueFromArray = arrayVariableName [index]; 

在下面的例子中,我们可以假定MyScript是我们的剧本的名字。

。您需要可以保存名称和int数组名称的字典。

Dictionary<string, int[]> boxes 

。你需要一种方法来"box"+2arrayVariableName转换为当前的脚本实例。这可以通过C#中的隐式转换运算符功能来完成。您可以将"box"+2arrayVariableName合并到此隐式MyScript中,然后将其存储到全局变量中以用于下一步。

//The global variable that holds the arrayVariableName to access 
static string targetBox = null; 

//Implicit conversion operators (box array name to this script(MyScript) instance) 
public static implicit operator MyScript(string box) 
{ 
    return setTargetAndGetInstance(box); 
} 

public static MyScript setTargetAndGetInstance(string box) 
{ 
    if (instance.boxes.ContainsKey(box)) 
    { 
     //Set the box requested. This will be needed in the Indexer overloading above 
     targetBox = box; 
     return instance; 
    } 
    else 
     return null; 
} 

。现在,你可以实现[index]语法。这可以通过索引器重载功能来完成。

//Indexer overloading (index to int (value in array)) 
public int this[int index] 
{ 
    get 
    { 
     //Get value based on value set in the implicit operators 
     return accessBox(targetBox, index); 
    } 
} 

现在,当你这样做,"box"+2,它将与implicit转换操作符的帮助下返回这个(MyScript)的实例。然后它将允许您使用索引器重载功能执行[random int]


下面的代码是在你的问题和其他类似的方法来做到这一点的语法的例子。 包括相似的人,因为他们看起来比更好的你是什么要求

用一个简单的功能:

int test1 = accessBox("box" + 2, UnityEngine.Random.Range(0, 3)); 
Debug.Log(test1); 

随着arrayVariableName [index]语法:

您正在寻找这一点,但铸造MyScript看起来很糟糕

int test2 = ((MyScript)("box" + 2))[UnityEngine.Random.Range(0, 3)]; 
Debug.Log(test2); 

随着[arrayVariableName][index]语法:

int test3 = this["box" + 2][UnityEngine.Random.Range(0, 3)]; 
Debug.Log(test3); 

随着[arrayVariableName, index]语法

int test4 = this["box" + 2, UnityEngine.Random.Range(0, 3)]; 
Debug.Log(test4); 

完整的功能例如:

using System.Collections.Generic; 
using UnityEngine; 

public class MyScript : MonoBehaviour 
{ 

    public int[] box1 = { 1, 0, 2 }; 
    public int[] box2 = { 3, 1, 0 }; 
    public int[] box3 = { 2, 3, 1 }; 


    public Dictionary<string, int[]> boxes = new Dictionary<string, int[]>(); 
    private static MyScript instance; 

    void Awake() 
    { 
     instance = this; 

     //Add to Dictionary 
     addBox(); 

     int test1 = accessBox("box" + 2, UnityEngine.Random.Range(0, 3)); 
     Debug.Log(test1); 

     int test2 = ((MyScript)("box" + 2))[UnityEngine.Random.Range(0, 3)]; 
     Debug.Log(test2); 

     int test3 = this["box" + 2][UnityEngine.Random.Range(0, 3)]; 
     Debug.Log(test3); 

     int test4 = this["box" + 2, UnityEngine.Random.Range(0, 3)]; 
     Debug.Log(test4); 
    } 

    void addBox() 
    { 
     boxes.Add("box1", box1); 
     boxes.Add("box2", box2); 
     boxes.Add("box3", box3); 
    } 

    public int accessBox(string box, int index) 
    { 
     //Return the array from the Dictionary 
     int[] tempVar; 
     if (boxes.TryGetValue(box, out tempVar)) 
     { 
      //Return the spicified index 
      return tempVar[index]; 
     } 
     else 
     { 
      //ERROR - return -1 
      return -1; 
     } 
    } 


    //Indexer overloading (index to int (value in array)) 
    public int this[int index] 
    { 
     get 
     { 
      //Get value based on value set in the implicit operators 
      return accessBox(targetBox, index); 
     } 
    } 

    static string targetBox = null; 

    //Implicit conversion operators (box array name to this script(MyScript) instance) 
    public static implicit operator MyScript(string box) 
    { 
     return setTargetAndGetInstance(box); 
    } 

    public static MyScript setTargetAndGetInstance(string box) 
    { 
     if (instance.boxes.ContainsKey(box)) 
     { 
      //Set the box requested. This will be needed in the Indexer overloading above 
      targetBox = box; 
      return instance; 
     } 
     else 
      return null; 
    } 

    //Indexer overloading (box array name to this script(MyScript) instance) 
    public MyScript this[string box] 
    { 
     get 
     { 
      return setTargetAndGetInstance(box); 
     } 
    } 

    //Indexer overloading (box array name to int) 
    public int this[string box, int index] 
    { 
     get 
     { 
      setTargetAndGetInstance(box); 
      return accessBox(box, index); 
     } 
    } 
} 
1

这里是一个通用的解决问题的方法,使用Dictionary<TKey,TValue>

主要代码:

using System; 
using System.Collections.Generic; 

public class Class1 
{ 
    public void Example() 
    { 
     // a dictionary with string keys 

     var string1 = "abcd"; 
     var string2 = "efgh"; 

     var dictionary1 = new Dictionary<string, int[]> 
     { 
      {string1, new[] {0, 1, 2}}, 
      {string2, new[] {3, 4, 5}} 
     }; 


     // a dictionary with custom type 

     var box1 = new Box(10, 10); 
     var box2 = new Box(20, 20); 

     var dictionary2 = new Dictionary<Box, int[]> 
     { 
      {box1, new[] {0, 1, 2}}, 
      {box2, new[] {3, 4, 5}} 
     }; 

     // get random value from both dictionnaries 

     var i1 = GetRandomInteger(dictionary1, string1); 
     var i2 = GetRandomInteger(dictionary2, box1); 
    } 

    private int GetRandomInteger<TKey>(IDictionary<TKey, int[]> dictionary, TKey key) 
    { 
     if (!dictionary.ContainsKey(key)) 
      throw new KeyNotFoundException(); 

     var array = dictionary[key]; 

     // prefer UnityEngine.Random here since it's static 
     var index = new Random().Next(array.Length); 

     var value = array[index]; 

     return value; 
    } 
} 

额外的代码:

public struct Box 
{ 
    // a dictionary key should be immutable, therefore I use a struct 
    // implement equality members so that when querying the dictionary, 
    // it will find the value associated to the key 
    // see https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type 

    public int Width { get; } 
    public int Height { get; } 

    public Box(int width, int height) 
    { 
     Width = width; 
     Height = height; 
    } 

    public bool Equals(Box other) 
    { 
     return Width == other.Width && Height == other.Height; 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) 
      return false; 
     return obj is Box && Equals((Box) obj); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      return (Width * 397)^Height; 
     } 
    } 

    public static bool operator ==(Box left, Box right) 
    { 
     return left.Equals(right); 
    } 

    public static bool operator !=(Box left, Box right) 
    { 
     return !left.Equals(right); 
    } 
}