C# 随机选择两个不同的对象会导致对象引用相同的值
我正在尝试编写一个函数,该函数将随机建议两个城市之间或同一城市之间但邮政编码不同的起点和目的地。我有一门课要做这件事:C# 随机选择两个不同的对象会导致对象引用相同的值,c#,pass-by-reference,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
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;
}
}
当我在调用designation city get city函数之前设置断点时,origin city的值与函数调用完成时的值不同,因此我确信originCity变量在某处引用destinationCity,我只是不确定为什么或如何修复它在您的示例中有一半的时间,因为在
城市的列表中只有两个CityInfo
对象。当为始发地和目的地选择相同的城市时,对象是相同的,因此由GetRandom(city.Zipcodes,random)
选择的Zip
属性将由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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间stackOverflowRandomRefTest
{
班级计划
{
静态void Main(字符串[]参数)
{
var random=新的random();
对于(int i=0;i<10;i++)
{
var originCity=CityInfo.GetCity(随机,空);
var destinationCity=CityInfo.GetCity(随机,原始);
WriteLine(String.Format(“orig:{0}{1}”,originCity.CityName,originCity.Zip));
WriteLine(String.Format(“dest:{0}{1}”,destinationCity.CityName,destinationCity.Zip));
}
Console.ReadKey();
}
}
公共类城市信息
{
公共字符串CityName{get;set;}
公共字符串状态{get;set;}
公共字符串Zip{get;set;}
公共IEnumerable ZipCodes{get;set;}
私有静态只读IEnumerable Cities=new[]{
新城市信息{
CityName=“纽约”,
State=“NY”,
ZipCodes=new[]{“10001”、“10002”、“10003”、“10004”、“10005”}
},
新城市信息
{
CityName=“华盛顿”,
State=“DC”,
ZipCodes=new[]{“20001”、“20002”、“20003”、“20004”、“20005”}
}
};
私有静态T GetRandom(IEnumerable列表,随机生成器)
{
int n=generator.Next(list.Count());
控制台写入线(n);
return list.ToArray()[n];
}
公共静态城市信息获取城市(随机,城市信息非本市)
{
var city=GetRandom(城市,随机);
while(城市==非本市)
{//如果只有一个城市,这是无限的。。。
城市=GetRandom(城市,随机);
}
city.Zip=GetRandom(city.ZipCodes,random);
回归城市;
}
}
}
您每次都重新输入随机数生成器-这将产生相同的“随机”数。实际上并非如此,每个城市的值都不同,但当设置目标城市时,原点城市的值会发生变化,但为了确保我编辑了代码,并且代码的行为完全相同,如果其他任何人有此问题,则问题实际上是由DetCity中的city变量作为Cities IEnumerable的引用传递引起的。如果选择了同一个城市,则引用被传回,并且在一个项目(如目的地城市)中更改zip也将在原始城市中更改,因为两个对象引用相同的数组元素,如果选择了同一个城市,则导致它们都是相同的。当您更新问题时,您的问题与我的重复问题不同重新开始你的问题。请将您找到的解决方案作为答案发布,以便其他人可以从您的发现中受益。Next
在随机化工具上期望的是独占的最大值,而不是包含的最大值。因此,它应该是generator.Next(list.Count()-1)
,而不是generator.Next(list.Count())
。例如,generator.Next(3)
将为您提供0、1或2。
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;
}
}
}