0

I am randomly generating a list of Sales objects:

public class Sale
{
    public string Name { get; set; }
    public List<Product> Products { get; set; }
    public decimal Value
    {
        get { return Products.Sum(p => p.Price); }
    }
}

public class Product
{
    public decimal Price { get; set; }
}

Using this setup:

private void SetProducts()
{
    var seed = (int)(DateTime.UtcNow.Ticks | 0x0000FFFF);
    var random = new Random(seed);
    Products = new List<Product>();
    for(var i = 0; i < 100; i++)
    {
        Products.Add(new Product
        {
            Price = random.Next(500, 1500)
        });
    }
}

private void SetSales()
{
    Sales = new List<Sale>();
    for(var i = 0; i < 100; i++)
    {
        Sales.Add(new Sale{
        Name = "Sale #" + i,
        Products = GetProducts()
        }
    }
}

private List<Product> GetProducts()
{
    var seed = (int) (DateTime.UtcNow.Ticks | 0x0000FFFF);
    var random = new Random(seed);
    var max = random.Next(1, 7);
    var products = new List<Product>();
    for(var i = 0; i < max; i++)
    {
        products.Add(Products[random.Next(Products.Count)];
    }
    return products;
}

public Dashboard()
{
    SetProducts();
    SetSales();
}

When I evaluate these sales values, they all have the exact same value. When I walk through the debugger and evaluate them, the evaluated sales have the correct value, but all of the sales whose evaluation waited until this object was passed down to the View (this is part of a mock MVC dashboard) all of the data is identical. This makes me believe that the Products field is being computed lazily, but how can I fix this? I was under the impression that this might be an issue if I were using a different Enumerable, but I was of the opinion that a List<T> would not have this problem.

EDIT: I also want to mention that even if the products field is being computed lazily, I have a hard time believe that all of that computation is being done within the same tick. A tick should be around 100ns and while I know C# is a very efficient language, I have a hard time believing it could do all of that in less than 100ns.

jokul
  • 1,269
  • 16
  • 37
  • 4
    See duplicate, create your `new Random()` otuside any loop. – CodeCaster Jan 12 '15 at 20:32
  • 3
    Just because a tick is 100ns doesn't mean DateTime.Now has tick resolution. try this to prove it: `for (int i = 0; i < 10; i++) Console.WriteLine(DateTime.UtcNow.Ticks);` – Rotem Jan 12 '15 at 20:33
  • @Rotem That, unlike the OP's code, is code that actually *could* execute within one single tick. You're quite right that DateTime has far less resolution that that, but that's not a reasonable way of demonstrating that fact. – Servy Jan 12 '15 at 20:33
  • @Servy So change the `10` to `1000000` :P – Rotem Jan 12 '15 at 20:34
  • Ah that's a good point, I thought I had resolved the issue brought up in the other questionby using that. I'll go and make that change. @Servy It's possible that in my laziness I only checked the first 20 or so results which may have been possible to execute within DateTime's tick resolution window. – jokul Jan 12 '15 at 20:35
  • @Rotem it's easier to just go to the documentation of that property, where it lists the approximate resolution. – Servy Jan 12 '15 at 20:35
  • 1
    @jokulmorder The resolution of `DateTime.Now` is ~10 milliseconds. – Servy Jan 12 '15 at 20:36

0 Answers0