I have a value (struct instance) that was cast to object for generic handling. I need to make a copy of the value. I cannot do this explicitly because I just have its Type and don't know what it is in compile time.
By default I get a copy of reference: var copy = objectOfMyStruct;. I thought about making an explicit shallow copy by MemberwiseClone() but I cannot do this because it's protected method and I cannot modify MyStruct.
Convert.ChangeType(objectOfMyStruct, typeOfMyStruct) doesn't help because conversion (actually no conversion) happens inside and it returns Object again.
How could I do this?
EDIT:
I need to make a copy to preserve original value and just deserialized one to pass to OnChangeHandler. Simplified implementation is:
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);
Copy is made because only delta (changes) are sent so should be applied to the original value.
EDIT 2:
This implementation works fine for primitive types, so despite int is boxed too I'm copying it instead of copying reference to it. I just don't understand this.
Here is an example of what is needed.
This example, which you can test in LINQPad should make a clone of the struct without casting it back to its unboxed type, so that when it is mutated by a call through the implemented interface, only the original is mutated. The question is thus; how do I write that Clone method?
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";
    }
}
 
     
     
     
     
    