C# 列表中的对象重复

问题描述 投票:0回答:3

我正在尝试使用对象列表创建一个简单的模拟,并使其重复执行计算来代表农民。它有一种方法可以按随机百分比增加农民拥有的资金量,每个农民的起始金额为 100 美元

    public class Farmer
    {
    public decimal money { get; set; }

    public Farmer()
    {
        money = 100;
    }

    public void doOneYear() //Represents how much money the farmer earned
    {
        Random random = new Random();
        decimal growth = random.Next(0, 100);
        decimal percentage = (growth / 1000);
        money = money * (1 + percentage);
    }
}

运行的代码是这样的

        List<Farmer> farmers = new List<Farmer>();

        int count = 0;

        while (count < 10)
        {
            Farmer newFarmer = new Farmer();
            farmers.Add(newFarmer);
            count++;
        }


        foreach(var farmer in farmers)
        {
            int years = 0;
            while (years < 10)
            {
                farmer.doOneYear();
                years++;
            }
        }


        foreach (var farmer in farmers)
        {
            MessageBox.Show(farmer.money.ToString());
        }

但是我得到的结果只是列表中重复的第一个对象。如果我在调试模式下逐步完成整个过程,它工作正常,但当我让它运行时,对象似乎是重复的。

c# list random
3个回答
1
投票

来自 MSDN:“默认种子值源自系统时钟,并且具有有限的分辨率。因此,通过调用默认构造函数连续创建的不同 Random 对象将具有相同的默认种子值,因此,将产生相同的随机数集。”

我个人只是将 Random 实例设为静态成员:

public class Farmer
{
    public decimal money { get; set; }
    private static Random random = new Random();

    public Farmer()
    {
        money = 100;
    }

    public void doOneYear() //Represents how much money the farmer earned
    {
        decimal growth = random.Next(0, 100);
        decimal percentage = (growth / 1000);
        money = money * (1 + percentage);
    }
}

0
投票

由于程序运行速度如此之快,并且我相信 Random 类使用时间设置作为其默认种子,因此您需要自己将种子注入到 Random 调用中。 (这也可能是为什么您在调试时会看到不同的数字 - 您使程序运行得更慢,因此 Random 类会输出不同的数字)。

我这样做了,并在输出中看到每个农民的数字不同。不过,您可能想使用不同的种子生成。

    public class Farmer
    {
        private static int seed = 17;

        public decimal money { get; set; }
        public int FarmerID { get; set; }
        public Farmer(int id)
        {
            money = 100;
            FarmerID = id;
        }

        public void doOneYear() //Represents how much money the farmer earned
        {
            seed++;
            Random random = new Random(seed);
            decimal growth = random.Next(0, 100);
            decimal percentage = (growth / 1000);
            money = money * (1 + percentage);
        }
    }

0
投票
public class MyRandom
{
    public static Random _random = new Random();
    public Random Random
    {
        get
        {
            if (_random == null)
                _random = new Random();
            return _random;
        }
    }
}
public class Farmer
{
    public decimal money { get; set; }

    public Farmer()
    {
        money = 100;
    }

    public void doOneYear() //Represents how much money the farmer earned
    {
        MyRandom random = new MyRandom();
        decimal growth = random.Random.Next(0, 100);
        decimal percentage = (growth / 1000);
        money = money * (1 + percentage);
    }
}

您可以为 Random 实现一个自定义类,并对 Random 对象使用单例方法,这样您就可以使用新的 MyRandom 并获得所需的结果,而无需修改您的 Farmer 类。

List<Farmer> farmers = new List<Farmer>();
int count = 0;

while (count < 10)
{
    Farmer newFarmer = new Farmer();
    farmers.Add(newFarmer);
    count++;
}


foreach (var farmer in farmers)
{
    int years = 0;
    while (years < 10)
    {
        farmer.doOneYear();
        years++;
    }
}

foreach (var farmer in farmers)
{
    Console.WriteLine(farmer.money.ToString());
}

结果:

(我使用LinqPad进行测试)

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.