有没有一种有效的方法来从结构中获取随机值?

时间:2019-08-12 08:08:01

标签: c# unity3d

我有一个结构,它具有相同的类型属性:

public struct SomeTypes
{
    public string type1;
    public string type2;
    public string type3;
    public string type4;
}

它们都被分配了唯一值。我需要做的就是从此结构中获取一个随机值。

例如:

SomeTypes myTypes;

private string GetRandomType(){
    //Instead of:
    return myTypes.type1; //Or type2 etc.
    //This is what I want:
    return myTypes.takeOneRandom();
}

对于这种类型的问题,这可能是一个复杂的解决方案,但是如果可能的话,我想知道如何使用结构来实现。

4 个答案:

答案 0 :(得分:2)

  

我有固定数量的“类型”,更确切地说,是在编辑器中分配的精灵

我只是用给定的字段初始化一个数组,并使用它来使用Random.Range

来获得一个随机条目。
[Serializable]
public struct YourStruct
{
    public Sprite sprite1;
    public Sprite sprite2;
    public Sprite sprite3;
    public Sprite sprite4;

    private Sprite[] sprites;

    public Sprite RandomSprite
    {
        get
        {
            // lazy initialization of array
            if (sprites == null) sprites = new[] { sprite1, sprite2, sprite3, sprite4 };

            // pick random
            return sprites[UnityEngine.Random.Range(0, sprites.Length)];
        }
    }
}

以后再使用

public YourStruct yourStruct;

...

Sprite randomSprite = yourStruct.RandomSprite;

答案 1 :(得分:1)

这应该通过反射来解决问题:

void Main()
{
     SomeTypes s = new SomeTypes();
    s.type1 = "asdsad";
    s.type2 = "damn";
    s.type3 = "damn1";
    s.type4 = "damn2";

    var t = typeof(SomeTypes).GetFields(); // get all fields

    Random r = new Random();
    int rInt = r.Next(0, t.Length); // create a random number in range of property count

    var res = s.GetType().GetField(t[rInt].Name); // get random property name

    var randomValue = res.GetValue(s);//get that property value
}

public struct SomeTypes
{
    public string type1;
    public string type2;
    public string type3;
    public string type4;
}

这已经使用LinqPad进行了测试

答案 2 :(得分:0)

最简单的方法是重新格式化代码,并使用数组代替不同的字段:

public struct SomeTypes
{
    private Random random;
    public string[] types;

    public SomeTypes(IList<string> types)
    {
        this.types = (string[]) types;
        random = new Random();
    }

    public string takeOneRandom()
    {
        int index = random.Next(types.Length);
        return types[index];
    }
}
SomeTypes myTypes = new SomeTypes(new string[]{"t0", "t1", "t2", "t3"});

Console.WriteLine(myTypes.takeOneRandom());

如果您想保留自己的字段,可以做几件事。您可以为索引器提供一个开关,一个字典,或者,如其他答案所示,您可以使用反射。

这是带有索引器和开关的解决方案:

public struct SomeTypes
{
    private Random random;

    public string type1;
    public string type2;
    public string type3;
    public string type4;

    public SomeTypes(string t1, string t2, string t3, string t4)
    {
        type1 = t1;
        type2 = t2;
        type3 = t3;
        type4 = t4;
        random = new Random();
    }

    public string this[int idx]
    {
        get
        {
            switch (idx)
            {
                case 0 : return type1;
                case 1: return type2;
                case 2: return type3;
                case 3: return type4;
                default: throw new ArgumentException();
            }
        }
    }

    public string takeOneRandom()
    {
        int index = random.Next(4);
        return this[index];
    }
}
        SomeTypes myTypes = new SomeTypes("t0", "t1", "t2", "t3");

        Console.WriteLine(myTypes.takeOneRandom());

答案 3 :(得分:0)

由于您只想读取其中一个字段(顺便说一句应该是属性),因此我认为它是一个结构对您来说不是问题。您可以使用反射。您的struct实例将被自动装箱,但这只要您刚刚阅读就不会有问题。

代码如下:

    struct SomeStruct
    {
        private static PropertyInfo[] properties = typeof(SomeStruct).GetProperties();
        private static Random random = new Random();

        public string type1 { get; set; }
        public string type2 { get; set; }
        public string type3 { get; set; }
        public string type4 { get; set; }

        public string TakeOneRandom()
        {
            int index = random.Next(properties.Length);
            return properties[index].GetValue(this)?.ToString();
        }
    }