유니티엔진의 T Object.Instantiate<T>(T)는 큰 약점이 있는것만 같다
public static T Instantiate<T>(T original) where T : Object { Object.CheckNullArgument((object) original, "The Object you want to instantiate is null."); T obj = (T) Object.Internal_CloneSingle((Object) original); return !((Object) obj == (Object) null) ? obj : throw new UnityException("Instantiate failed because the clone was destroyed during creation. This can happen if DestroyImmediate is called in MonoBehaviour.Awake."); }
디컴파일하면 위와 같은데, 아무리 생각해도 맨 밑에 줄이 거슬린다
Object간의 ==연산자는 밑과 같이 오버로드 된다
public static bool operator ==(Object x, Object y) => Object.CompareBaseObjects(x, y);
private static bool CompareBaseObjects(Object lhs, Object rhs) { bool flag1 = (object) lhs == null; bool flag2 = (object) rhs == null; if (flag2 & flag1) return true; if (flag2) return !Object.IsNativeObjectAlive(lhs); return flag1 ? !Object.IsNativeObjectAlive(rhs) : lhs.m_InstanceID == rhs.m_InstanceID; }
private static bool IsNativeObjectAlive(Object o) { if (o.GetCachedPtr() != IntPtr.Zero) return true; return !(o is MonoBehaviour) && !(o is ScriptableObject) && Object.DoesObjectWithInstanceIDExist(o.GetInstanceID()); }
[NativeMethod(IsFreeFunction = true, IsThreadSafe = true, Name = "UnityEngineObjectBindings::DoesObjectWithInstanceIDExist")] [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool DoesObjectWithInstanceIDExist(int instanceID);
저 작업들을 전부 수행하는건 귀찮으니 이렇게 바꿔주자
public static partial class ObjectUtility { private delegate Object ObjectCopier(Object obj); private static ObjectCopier _copier; private static ObjectCopier Copier => _copier ??= typeof(Object) .GetMethod("Internal_CloneSingle") ?.CreateDelegate(typeof(ObjectCopier)) is ObjectCopier method ? method : Object.Instantiate; [method: MethodImpl(MethodImplOptions.AggressiveInlining)] public static Object CopyObject(this Object obj) => Copier(obj); }
졸리니 테스트는 내일해야지...