У меня есть значение (экземпляр структуры), который был добавлен в object
для общей обработки. Мне нужно сделать копию значения. Я не могу сделать это явно, потому что у меня просто есть Type
и не знаю, что это такое во время компиляции.
По умолчанию я получаю копию ссылки: var copy = objectOfMyStruct;
. Я думал о создании явной мелкой копии MemberwiseClone()
, но я не могу этого сделать, потому что это защищенный метод, и я не могу изменить MyStruct
.
Convert.ChangeType(objectOfMyStruct, typeOfMyStruct)
не помогает, потому что внутри происходит преобразование (фактически никакого преобразования), и оно снова возвращает объект.
Как я могу это сделать?
EDIT:
Мне нужно сделать копию, чтобы сохранить исходное значение и просто десериализовать ее, чтобы перейти к OnChangeHandler. Упрощенная реализация:
var oldValue = type.GetValue(reference);
var newValue = oldValue; // something better is needed here
Deserialize(type, stream, ref newValue);
OnChange(oldValue, newValue);
type.SetValue(reference, newValue);
Копия создается, потому что отправляются только дельта (изменения), поэтому ее следует применять к исходному значению.
ИЗМЕНИТЬ 2:
Эта реализация отлично работает для примитивных типов, поэтому, несмотря на то, что int тоже в коробке, я копирую ее вместо копирования ссылки на нее. Я просто не понимаю этого.
Вот пример того, что необходимо.
Этот пример, который вы можете протестировать в LINQPad, должен сделать клон структуры без отбрасывания ее обратно на свой unboxed-тип, так что, когда он мутирован путем вызова через реализованный интерфейс, только оригинал мутирован. Таким образом, возникает вопрос: как написать этот метод Clone?
void Main()
{
object original = new Dummy { Property = 42, Field = "Meaning of life" };
object clone = Clone(original);
((IDummy)original).Mutate(); // will modify the boxed struct in-place
original.Dump();
// should output different if Clone did its job
clone.Dump();
}
static object Clone(object input)
{
return input;
}
public interface IDummy
{
void Mutate();
}
public struct Dummy : IDummy
{
public int Property { get; set; }
public string Field;
public void Mutate()
{
Property = 77;
Field = "Mutated";
}
}