C# 克隆包含许多对象并列出C的对象#
您好:)在winForm中克隆包含其他对象和列表的对象时遇到问题。 我想克隆结构类型为的对象,下面提供了类 首先,我尝试了浅克隆C# 克隆包含许多对象并列出C的对象#,c#,reference,clone,circular-reference,C#,Reference,Clone,Circular Reference,您好:)在winForm中克隆包含其他对象和列表的对象时遇到问题。 我想克隆结构类型为的对象,下面提供了类 首先,我尝试了浅克隆 public Structure Clone() { return this.MemberwiseClone() as Structure; } 我发现它不起作用,所以我搜索并做了一个深度克隆 还有这个 但是内部周期[,]被克隆为null 你能帮我@WiiMaxx吗 编辑2.0 我还检查了这篇关于3种方法中的深度克隆的文章,我认为我的代码中有循环引
public Structure Clone()
{
return this.MemberwiseClone() as Structure;
}
我发现它不起作用,所以我搜索并做了一个深度克隆
还有这个
但是内部
周期[,]
被克隆为null
你能帮我@WiiMaxx吗
编辑2.0
我还检查了这篇关于3种方法中的深度克隆的文章,我认为我的代码中有循环引用,这就是为什么这对我不起作用的原因
结束编辑好了,现在它应该真的可以工作了
(我还删除了我的旧解决方案,因为它完全不符合您的需要) Sub.cs C室
公共教室:iClonable
{
数据结构
{
内部int学生人数;
内部int-full;
内部字符串名称;
内部无接缝;
内部主题列表;
内部词典变体;
}
私人数据结构使用;
///
///科目表
///
内部主题列表
{
获取{return USE.subjects;}
设置{USE.subjects=value;}
}
公共房间(字符串名称、整数)
{
this.USE=new datenstuct();
this.USE.name=名称;
this.USE.studentsNumber=number;
this.USE.full=0;
this.USE.subjects=新列表();
this.USE.variations=新字典();
this.USE.freesets=编号;
}
公共房间(国际号码)
{
this.USE=new datenstuct();
this.USE.studentsNumber=number;
this.USE.full=0;
this.USE.subjects=新列表();
this.USE.variations=新字典();
this.USE.freesets=编号;
}
包房(datenStruct struc)
{
使用=结构;
}
公共业务添加主题(子sbj)
{
//还有东西
返回false;
}
公共bool附加部分主体(子sbj)
{
//东西
返回false;
}
公共对象克隆()
{
var copie=new datenstuct();
copie.studentsNumber=使用.studentsNumber;
copie.full=USE.full;
copie.freeSeats=使用.freeSeats;
var SubListCopie=新列表();
foreach(使用中的子origSub.主题)
SubListCopie.Add((Sub)origSub.Clone());
copie.subjects=子目录;
var SubDictCopie=新字典();
foreach(KeyValuePair KvP正在使用中。变体)
添加((Sub)KvP.Key.Clone(),KvP.Value);
copie.variations=子副本;
归还新房间(复印件);
}
}
Period.cs
公共课期间:可克隆
{
数据结构
{
内部名单室;
内部主题列表;
内部字符串名称;
内部冲突;
}
私人数据结构使用;
内部主题列表
{
获取{return USE.subjects;}
设置{USE.subjects=value;}
}
///
///创建类Period的实例
///
///这一时期的房间
公众时段(会议室列表)
{
this.USE.conflicts=0;
this.USE.rooms=房间;
this.USE.subjects=新列表();
填写受试者(参考使用房间、参考使用受试者);
}
专用期间(日期结构)
{
使用=结构;
}
///
///将房间中的主题填入主题列表
///
///参考房间清单
///参考受试者名单
私人主题(参考列表房间、参考列表主题)
{
foreach(房间中的var房间)
{
foreach(房间中的var主题。主题)
{
如果(!subject.Exists(s=>s.Name==subject.Name))
主题。添加(主题);
}
}
}
///
///如果任何房间中有位置,则将给定主题添加到句点
///
///要添加的主题
///如果为该主题添加了空格,则为true,否则为false
公共图书馆地址主题(子主题)
{
foreach(使用中的var房间。房间)
{
如果(房间地址主题)
{
//东西
}
其他的
if(房间添加部分主题)
{
//东西
}
}
返回false;
}
私有int计算冲突(子类)
{
//还有很多东西
返回1;
}
公共对象克隆()
{
var copie=new datenstuct();
copie.name=USE.name;
copie.conflicts=使用.conflicts;
var RoomListCopie=新列表();
foreach(使用中的房间或Sub.rooms)
添加((Room)origSub.Clone());
copie.rooms=房间列表copie;
var SubListCopie=新列表();
foreach(使用中的子origSub.主题)
SubListCopie.Add((Sub)origSub.Clone());
copie.subjects=子目录;
返回新期间(copie);
}
}
Structure.cs
公共类结构:IDisposable,ICloneable
{
数据结构
{
内部整数天;
内部int主语计数;
内部整数周期;
内部周期[,]数组;
内部名单室;
}
私人数据结构使用;
///
///计划中的天数
///
公众整数日
{
获取{return USE.days;}
设置{USE.days=value;}
}
内部名单室
{
获取{return USE.rooms;}
设置{USE.rooms=value;}
}
///
///创建结构对象的实例
///
///房间一览表
公共结构(整数天、整数周期、列表房间)
{
this.USE.days=天;
这个。使用。句号
public static T DeepClone<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
var backup=DeepClone<Structure>(this.sched); //sched is Structure Object
[Serializable]
public class Sub
{
string name;
int studentsNumber;
int unassaignedStudent;
public Sub(string name, int number)
{
this.name = name;
this.studentsNumber = number;
this.unassaignedStudent = number;
}
public Subject()
{
this.name = "";
this.studentsNumber = 0;
this.unassaignedStudent = 0;
}
public bool Assigne(int count)
{
//stuff
}
public Sub Clone()
{
return this.MemberwiseClone() as Sub;
}
}
[Serializable]
class Room
{
string name;
int studentsNumber;
int full;
private int freeSeats;
List<Sub> subjects;
/// <summary>
/// the list of subjects
/// </summary>
internal List<Sub> Subjects
{
get { return subjects; }
set { subjects = value; }
}
Dictionary<Subject, int> variations;
public Room(string name, int number)
{
this.name = name;
this.studentsNumber = number;
this.full = 0;
this.subjects = new List<Subject>();
this.variations = new Dictionary<Subject, int>();
this.freeSeats = number;
}
public Room(int number)
{
this.studentsNumber = number;
this.full = 0;
this.subjects = new List<Subject>();
this.variations = new Dictionary<Subject, int>();
this.freeSeats = number;
}
public Room()
{
this.name = "R" + count.ToString();
count++;
this.studentsNumber = 0;
this.full = 0;
this.subjects = new List<Sub>();
this.variation= new Dictionary<Sub, int>();
this.freeSeats = 0;
}
public bool addSubject(Sub sbj)
{
//also stuff
}
public bool addPartialSubject(Sub sbj)
{
//stuff
// return false;
}
public Room Clone()
{
return this.MemberwiseClone() as Room;
}
}
[Serializable]
class Period
{
List<Room> rooms;
int conflicts;
List<Sub> subjects;
internal List<Sub> Subjects
{
get { return subjects; }
set { subjects = value; }
}
/// <summary>
/// Create an instance of class Period
/// </summary>
/// <param name="rooms">the rooms in this Period</param>
public Period(List<Room> rooms)
{
this.conflicts = 0;
this.rooms = rooms;
subjects = new List<Subject>();
fillSubjects(ref rooms, ref subjects);
}
public Period()
{
this.conflicts = 0;
this.rooms = null;
subjects = new List<Subt>();
freeSeats = 0;
}
/// <summary>
/// Fill the subjects in the rooms to the list of subjects
/// </summary>
/// <param name="rooms">referance to the list of the rooms</param>
/// <param name="subjects">referance to the list of the subjects</param>
private void fillSubjects(ref List<Room> rooms, ref List<Sub> subjects)
{
foreach (var room in rooms)
{
foreach (var subject in room.Subjects)
{
if (!subjects.Exists(s => s.Name == subject.Name))
subjects.Add(subject);
}
}
}
/// <summary>
/// Adds the given subject to the period if there is a place in any room
/// </summary>
/// <param name="s">the subject to add</param>
/// <returns>true if there is space for this subject and added, otherwise false</returns>
public bool AddSubject(Sub s)
{
foreach (var room in rooms)
{
if (room.addSubject(s))
{
//stuff
}
else
if (room.addPartialSubject(s))
{
//stuff
}
}
return false;
}
private int CalculateConflictions(Sub s)
{
//also a lot of stuff
}
}
[Serializable]
class Structure:IDisposable
{
int days;
/// <summary>
/// the number of days in the Schedual
/// </summary>
public int Days
{
get { return days; }
set { days = value; }
}
int periods;
Period[,] schedualArray;
List<Room> rooms;
internal List<Room> Rooms
{
get { return rooms; }
set { rooms = value; }
}
/// <summary>
/// Creates an instance of the Structure object
/// </summary>
/// <param name="rooms">a list of the rooms in the Schedual</param>
public Structure(int days, int periods,List<Room> rooms)
{
this.days = days;
this.periods = periods;
this.rooms=rooms;
this.schedualArray = new Period[days, periods];
this.subjectCount = 0;
for (int i = 0; i < days; i++)
{
for (int j = 0; j < periods; j++)
{
schedualArray[i, j] = new Period(CloneList(ref rooms)); //here i cloned the list to be in the safe side and it didn't work also
}
}
}
public Structure()
{
this.days = 0;
this.totalEval = Int32.MaxValue;
this.periods = 0;
this.rooms = null;
this.subjectCount = 0;
this.schedualArray = null;
}
internal bool AddSubject(Sub subject, int day, int period)
{
//add the subject into inner lists (room)
}
public void PrintStruct()
{
for (int i = 0; i < days; i++)
{
for (int j = 0; j < periods; j++)
{
foreach (var subject in schedualArray[i, j].Subjects)
{
Console.Write("\t\t");
}
Console.Write("\t\t");
}
Console.WriteLine();
}
}
public Structure Clone()
{
return this.MemberwiseClone() as Structure;
}
public List<Room> CloneList(ref List<Room> rooms)
{
var lst = new List<Room>();
foreach (var room in rooms)
{
lst.Add(DeepClone<Room>(room));
}
return lst;
}
internal void RemoveSubject(Sub subject)
{
//..................
}
#region IDisposable Members
public void Dispose()
{
GC.Collect(g, GCCollectionMode.Forced);
}
#endregion
}
Structure backup=XamlClone(this.sched);
private Structure XamlClone(Structure s)
{
//First Step
// create a XAML string
string stCopie = XamlWriter.Save(s);
//Secound Step
// convert him back to an Object of YourTyp
return XamlReader.Load(XmlReader.Create(new StringReader(stCopie))) as Structure;
}
public class Sub: ICloneable
{
struct datenStruct
{
internal int studentsNumber;
internal int unassaignedStudent;
internal string name;
}
private datenStruct USE;
int studentsNumber;
public string Name
{
get { return USE.name; }
set { USE.name = value; }
}
private Sub(datenStruct struc)
{
this.USE = struc;
}
public Sub(string name, int number)
{
this.USE = new datenStruct();
this.USE.name = name;
this.USE.studentsNumber = number;
this.USE.unassaignedStudent = number;
}
public bool Assigne(int count)
{
//stuff
return true;
}
public object Clone()
{
var copie = new datenStruct();
copie.name = USE.name;
copie.unassaignedStudent = USE.unassaignedStudent;
copie.studentsNumber = USE.studentsNumber;
return new Sub(copie);
}
}
public class Room: ICloneable
{
struct datenStruct
{
internal int studentsNumber;
internal int full;
internal string name;
internal int freeSeats;
internal List<Sub> subjects;
internal Dictionary<Sub, int> variations;
}
private datenStruct USE;
/// <summary>
/// the list of subjects
/// </summary>
internal List<Sub> Subjects
{
get { return USE.subjects; }
set { USE.subjects = value; }
}
public Room(string name, int number)
{
this.USE = new datenStruct();
this.USE.name = name;
this.USE.studentsNumber = number;
this.USE.full = 0;
this.USE.subjects = new List<Sub>();
this.USE.variations = new Dictionary<Sub, int>();
this.USE.freeSeats = number;
}
public Room(int number)
{
this.USE = new datenStruct();
this.USE.studentsNumber = number;
this.USE.full = 0;
this.USE.subjects = new List<Sub>();
this.USE.variations = new Dictionary<Sub, int>();
this.USE.freeSeats = number;
}
private Room(datenStruct struc)
{
USE = struc;
}
public bool addSubject(Sub sbj)
{
//also stuff
return false;
}
public bool addPartialSubject(Sub sbj)
{
//stuff
return false;
}
public object Clone()
{
var copie = new datenStruct();
copie.studentsNumber = USE.studentsNumber;
copie.full = USE.full;
copie.freeSeats = USE.freeSeats;
var SubListCopie = new List<Sub>();
foreach (Sub origSub in USE.subjects)
SubListCopie.Add((Sub)origSub.Clone());
copie.subjects = SubListCopie;
var SubDictCopie = new Dictionary<Sub, int>();
foreach (KeyValuePair<Sub, int> KvP in USE.variations)
SubDictCopie.Add((Sub)KvP.Key.Clone(),KvP.Value);
copie.variations = SubDictCopie;
return new Room(copie);
}
}
public class Period: ICloneable
{
struct datenStruct
{
internal List<Room> rooms;
internal List<Sub> subjects;
internal string name;
internal int conflicts;
}
private datenStruct USE;
internal List<Sub> Subjects
{
get { return USE.subjects; }
set { USE.subjects = value; }
}
/// <summary>
/// Create an instance of class Period
/// </summary>
/// <param name="rooms">the rooms in this Period</param>
public Period(List<Room> rooms)
{
this.USE.conflicts = 0;
this.USE.rooms = rooms;
this.USE.subjects = new List<Sub>();
fillSubjects(ref USE.rooms, ref USE.subjects);
}
private Period(datenStruct struc)
{
USE = struc;
}
/// <summary>
/// Fill the subjects in the rooms to the list of subjects
/// </summary>
/// <param name="rooms">referance to the list of the rooms</param>
/// <param name="subjects">referance to the list of the subjects</param>
private void fillSubjects(ref List<Room> rooms, ref List<Sub> subjects)
{
foreach (var room in rooms)
{
foreach (var subject in room.Subjects)
{
if (!subjects.Exists(s => s.Name == subject.Name))
subjects.Add(subject);
}
}
}
/// <summary>
/// Adds the given subject to the period if there is a place in any room
/// </summary>
/// <param name="s">the subject to add</param>
/// <returns>true if there is space for this subject and added, otherwise false</returns>
public bool AddSubject(Sub s)
{
foreach (var room in USE.rooms)
{
if (room.addSubject(s))
{
//stuff
}
else
if (room.addPartialSubject(s))
{
//stuff
}
}
return false;
}
private int CalculateConflictions(Sub s)
{
//also a lot of stuff
return 1;
}
public object Clone()
{
var copie = new datenStruct();
copie.name = USE.name;
copie.conflicts = USE.conflicts;
var RoomListCopie = new List<Room>();
foreach (Room origSub in USE.rooms)
RoomListCopie.Add((Room)origSub.Clone());
copie.rooms = RoomListCopie;
var SubListCopie = new List<Sub>();
foreach (Sub origSub in USE.subjects)
SubListCopie.Add((Sub)origSub.Clone());
copie.subjects = SubListCopie;
return new Period(copie);
}
}
public class Structure : IDisposable,ICloneable
{
struct datenStruct
{
internal int days;
internal int subjectCount;
internal int periods;
internal Period[,] schedualArray;
internal List<Room> rooms;
}
private datenStruct USE;
/// <summary>
/// the number of days in the Schedual
/// </summary>
public int Days
{
get { return USE.days; }
set { USE.days = value; }
}
internal List<Room> Rooms
{
get { return USE.rooms; }
set { USE.rooms = value; }
}
/// <summary>
/// Creates an instance of the Structure object
/// </summary>
/// <param name="rooms">a list of the rooms in the Schedual</param>
public Structure(int days, int periods, List<Room> rooms)
{
this.USE.days = days;
this.USE.periods = periods;
this.USE.rooms = rooms;
this.USE.schedualArray = new Period[days, periods];
this.USE.subjectCount = 0;
for (int i = 0; i < days; i++)
{
for (int j = 0; j < periods; j++)
{
USE.schedualArray[i, j] = new Period(CloneList(ref rooms)); //here i cloned the list to be in the safe side and it didn't work also
}
}
}
private Structure(datenStruct struc)
{
this.USE = struc;
}
internal bool AddSubject(Sub subject, int day, int period)
{
//add the subject into inner lists (room)
return true;
}
public void PrintStruct()
{
for (int i = 0; i < USE.days; i++)
{
for (int j = 0; j < USE.periods; j++)
{
foreach (var subject in USE.schedualArray[i, j].Subjects)
{
Console.Write("\t\t");
}
Console.Write("\t\t");
}
Console.WriteLine();
}
}
public List<Room> CloneList(ref List<Room> rooms)
{
var lst = new List<Room>();
foreach (var room in rooms)
{
lst.Add((Room)room.Clone());
}
return lst;
}
internal void RemoveSubject(Sub subject)
{
//..................
}
#region IDisposable Members
public void Dispose()
{
// GC.Collect(g, GCCollectionMode.Forced);
}
#endregion
public object Clone()
{
var copie =new datenStruct();
copie.days = USE.days;
copie.subjectCount = USE.subjectCount;
copie.periods = USE.periods;
var RoomListCopie = new List<Room>();
foreach (Room origSub in USE.rooms)
RoomListCopie.Add((Room)origSub.Clone());
copie.rooms = RoomListCopie;
copie.schedualArray = new Period[copie.days, copie.periods];
for (int i = 0; i < copie.days; i++)
{
for (int j = 0; j < copie.periods; j++)
{
copie.schedualArray[i, j] = new Period(CloneList(ref copie.rooms));
}
}
return new Structure(copie);
}
}
private Structure SpecialClone(Structure s)
{
var rooms = Cloner.DeepClone<List<Room>>(s.Rooms);
var perds = Cloner.DeepClone<Period[,]>(s.SchedualArray);
var days = s.Days;
var periods = s.Periods;
return new Structure(days, periods, rooms, perds, s.SubjectCount);
}
public Structure(int days, int periods, List<Room> rooms, Period[,] _periods,int subjectCount)
{
this.days = days;
this.periods = periods;
this.rooms = rooms.DeepClone();
this.subjectCount = subjectCount;
this.schedualArray = _periods.Clone() as Period[,];
}