So I'm working on an equipment system where I have some Item template classes, than i want to clone each time a new item is instantiated for this i have this bit:
public Item(Item clone)
{
this.name = clone.name;
this.description = clone.description;
this.icon = clone.icon;
this.mesh = clone.mesh;
this.weight = clone.weight;
this.price = clone.price;
}
Can this part be write any smarter in a one line format, that I dont have to update each time i add a new parameter?
Next i inherit a bunch of subclass from Item and to clone these i have made a static class:
public static dynamic EquipmentClone(dynamic toClone)
{
switch (toClone)
{
case Item_Armor item: return new Item_Armor(toClone);
case Item_Weapon item: return new Item_Weapon(toClone);
case Item_Equipment item: return new Item_Equipment(toClone);
case Item item: return new Item(toClone);
default: return null;
}
}
This way i can just pass an item into the method and it will instantiate and output a clone of the corresponding type. Can this part be made into a one liner? maybe using generics?
Try this out:
private object DeepCopy(object obj) {
if (obj == null)
return null;
Type type = obj.GetType();
if (type.IsValueType || type == typeof(string)) {
return obj;
}
else if (type.IsArray) {
Type elementType = Type.GetType(
type.FullName.Replace("[]", string.Empty));
var array = obj as Array;
Array copied = Array.CreateInstance(elementType, array.Length);
for (int i = 0; i < array.Length; i++) {
copied.SetValue(DeepCopy(array.GetValue(i)), i);
}
return Convert.ChangeType(copied, obj.GetType());
}
else if (type.IsClass) {
object toret = Activator.CreateInstance(obj.GetType());
FieldInfo[] fields = type.GetFields(BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo field in fields) {
object fieldValue = field.GetValue(obj);
if (fieldValue == null)
continue;
field.SetValue(toret, DeepCopy(fieldValue));
}
return toret;
}
else
throw new ArgumentException("Unknown type");
}
add at the top:
using System.Reflection;
And cast to the new type the returned object like this for example:
Item_Armor clonedVarName = (Item_Armor)DeepCopy(cloneSourceVarName);
You dont have to copy your class elements field by field as that is handled by the method above. If that does not work here there are some ideas. I got the posted example from there and directly worked for me.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.