Как можно изменить тип объекта в рантайме?

Можно ли какими-то средствами C# изменить тип какого-то объекта на любой другой в рантайме?


Ответы (1 шт):

Автор решения: Kalmankantaja

Да, можно. Необходимо получить поинтер на тип объекта, а затем получить поинтер на нужный вам тип и присвоить значение. Выглядеть это будет вот так (можно на самом деле переписать на generic и изменить немного typeof):

unsafe void ChangeType(byte[] arr)
{
    void** ptr = *(void***)(Unsafe.AsPointer(ref arr)); //поинтер на тип объекта arr
    *ptr = (void*)typeof(void).TypeHandle.Value; //поинтер на нужный нам тип. Вместо typeof(void) может быть typeof(ваш_тип)
}

Однако, у такого действия есть побочный эффект, если GC закинет его в SOH, то после Compact возможно будет изменён адрес памяти. Для LOH этого не произойдет.

Теперь, после выполнения этого метода (если смотреть в Debugger), тип будет void, однако это всё равно не запрещает нам итерировать и по-другому взаимодействовать с объектом как с типом который был изначально

var arr = new byte[] {1,2,3};
ChangeType(arr);
Console.WriteLine(byteArr.GetType());

//Вывод: System.Void
→ Ссылка