欢迎加入Unity业内qq交流群:956187480



在把一个对象赋值给另外一个同类型的对象时,意味着两个对象的堆栈信息是一样的。当你想把对象的某一个属性更改后再添加到一个列表的时候,就会被最后的对象替换掉,就不能实现新对象的添加。下面两种方式可以实现对象赋值给同类型的对象,这两个对象的堆栈信息是不一样的。

方法一:

必须对对象进行序列化处理

public static object DeepClone(object obj)
{
BinaryFormatter bFormatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
bFormatter.Serialize(stream, obj);
stream.Seek(0, SeekOrigin.Begin);
return bFormatter.Deserialize(stream);
}

测试:

[Serializable]
class User
{
public User(){}
public int id;
public string name;
public User(int id, string name)
{
this.id = id;
this.name = name;
}
}

public class test : MonoBehaviour {
List<User> users;
User user;
// Use this for initialization
void Start () {
users = new List<User>();
user = new User(2,"小花");
}
int b = 5;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
var a = new User();
a = GameTool.DeepClone(user) as User;
a.id = b++;
users.Add(a);
}
}
}

方法二:

public static object CopyObject(object obj)
{
object targetDeepCopyObj;

if (obj == null)
{
Debug.Log("copy obj is null");
}
var targetType = obj.GetType();
//值类型
if (targetType.IsValueType == true)
{
targetDeepCopyObj = obj;
}
//引用类型
else
{
targetDeepCopyObj = Activator.CreateInstance(targetType); //创建引用对象
MemberInfo[] memberCollection = obj.GetType().GetMembers();

foreach (MemberInfo member in memberCollection)
{
if (member.MemberType == MemberTypes.Field)
{
FieldInfo field = (FieldInfo)member;
object fieldValue = field.GetValue(obj);
if (fieldValue is ICloneable)
{
field.SetValue(targetDeepCopyObj, (fieldValue as ICloneable).Clone());
}
else
{
field.SetValue(targetDeepCopyObj, CopyObject(fieldValue));
}

}
else if (member.MemberType == MemberTypes.Property)
{
PropertyInfo myProperty = (PropertyInfo)member;
MethodInfo info = myProperty.GetSetMethod(false);
if (info != null)
{
object propertyValue = myProperty.GetValue(obj, null);
if (propertyValue is ICloneable)
{
myProperty.SetValue(targetDeepCopyObj, (propertyValue as ICloneable).Clone(), null);
}
else
{
myProperty.SetValue(targetDeepCopyObj, CopyObject(propertyValue), null);
}
}
}
}
}
return targetDeepCopyObj;
}
public static void CopyObject(object source, object target)
{
var targetType = target.GetType();
if (targetType == null)
{
targetType = source.GetType();
}
//值类型
if (targetType.IsValueType == true)
{
target = source;
}
//引用类型
else
{
if (source == null)
{
return;
}
MemberInfo[] memberCollection = source.GetType().GetMembers();

foreach (MemberInfo member in memberCollection)
{
if (member.MemberType == MemberTypes.Field)
{
FieldInfo field = (FieldInfo)member;
object fieldValue = field.GetValue(source);
if (fieldValue is ICloneable)
{
field.SetValue(target, (fieldValue as ICloneable).Clone());
}
else
{
field.SetValue(target, CopyObject(fieldValue));
}

}
else if (member.MemberType == MemberTypes.Property)
{
PropertyInfo myProperty = (PropertyInfo)member;
MethodInfo info = myProperty.GetSetMethod(false);
if (info != null)
{
object propertyValue = myProperty.GetValue(source, null);
if (propertyValue is ICloneable)
{
myProperty.SetValue(target, (propertyValue as ICloneable).Clone(), null);
}
else
{
myProperty.SetValue(target, CopyObject(propertyValue), null);
}
}

}
}
}
}

测试:

class User
{
public User(){}
public int id;
public string name;
public User(int id, string name)
{
this.id = id;
this.name = name;
}
}

public class test : MonoBehaviour {
List<User> users;
User user;
// Use this for initialization
void Start () {
users = new List<User>();
user = new User(2,"小花");
}
int b = 5;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
var a = new User();
a = GameTool.CopyObject(user) as User;
a.id = b++;
users.Add(a);
}
}
}

测试结果keyu可以断点查看users数据


欢迎加入Unity业内qq交流群:956187480