随机选择两个不同的对象会导致对象引用相同的值

时间:2014-11-26 17:24:52

标签: c# pass-by-reference

我正在尝试编写一个函数,该函数将随机建议在两个城市之间或同一城市之间但不同邮政编码之间旅行的起点和目的地。我有一节课要做:

public class CityInfo
{
    public string CityName { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public IEnumerable<string> ZipCodes { get; set; }

    private static readonly IEnumerable<CityInfo> Cities = new []{
        new CityInfo{
            CityName = "New York",
            State = "NY",
            ZipCodes = new[]{"10001", "10002", "10003", "10004", "10005"}
        },
        new CityInfo
        {
            CityName = "Washington",
            State="DC",
            ZipCodes = new []{"20001", "20002", "20003", "20004","20005"}
        }
    };

    private static T GetRandom<T>(IEnumerable<T> list, Random generator)
    {
        return list.ToArray()[generator.Next(list.Count() - 1)];
    }

    public static CityInfo GetCity(Random random)
    {
        var city = GetRandom(Cities, random);
        city.Zip = GetRandom(city.ZipCodes, random);
        return city;
    }

}

我遇到的问题是,当我使用Get City方法选择两个城市时,两个城市都会出现相同的值。我打电话给他们如下:

var random = new Random();
var originCity = CityInfo.GetCity(random);
var destinationCity = CityInfo.GetCity(random);

当我在调用desination city之前设置一个断点获取city函数时,origin city的值与函数调用完成时的值不同,所以我相信originCity变量在某个地方引用destinationCity我不知道为什么或如何解决它

1 个答案:

答案 0 :(得分:1)

在您的示例中,原始城市与目的地的大约一半相同,因为CityInfo列表中只有两个Cities个对象。当为起点和终点选择相同的城市时,对象是相同的,因此Zip选择的GetRandom(city.Zipcodes, random)属性再次由Zip上的目的地呼叫集再次设置。

如果您想允许原始城市和目的地城市相同CityName但是Zip不同,则需要创建对象的副本(至少对于原点)。请注意,您可能仍然会随机地将目的地等于目的地。

如果您可以要求原点和目的地不同CityNames,则以下代码将选择随机来源和目标CityInfo对象。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace stackOverflowRandomRefTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var random = new Random();
            for (int i = 0; i < 10; i++)
            {
                var originCity = CityInfo.GetCity(random, null);
                var destinationCity = CityInfo.GetCity(random, originCity);
                Console.WriteLine(String.Format("orig: {0} {1}",originCity.CityName, originCity.Zip));
                Console.WriteLine(String.Format("dest: {0} {1}",destinationCity.CityName, destinationCity.Zip));
            }
            Console.ReadKey();
        }
    }
    public class CityInfo
    {
        public string CityName { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
        public IEnumerable<string> ZipCodes { get; set; }

        private static readonly IEnumerable<CityInfo> Cities = new[]{
        new CityInfo{
            CityName = "New York",
            State = "NY",
            ZipCodes = new[]{"10001", "10002", "10003", "10004", "10005"}
        },
        new CityInfo
        {
            CityName = "Washington",
            State="DC",
            ZipCodes = new []{"20001", "20002", "20003", "20004","20005"}
        }
        };

        private static T GetRandom<T>(IEnumerable<T> list, Random generator)
        {
            int n = generator.Next(list.Count());
            Console.WriteLine(n);
            return list.ToArray()[n];
        }

        public static CityInfo GetCity(Random random, CityInfo notThisCity)
        {
            var city = GetRandom(Cities, random);
            while (city == notThisCity)
            {  // if there is only one city this is infinite...
                city = GetRandom(Cities, random);
            }
            city.Zip = GetRandom(city.ZipCodes, random);
            return city;
        }

    }
}