object
一般的な処理のためにキャストされた値 (構造体インスタンス) があります。値のコピーを作成する必要があります。私はそれを持っているだけType
で、コンパイル時にそれが何であるかわからないため、これを明示的に行うことはできません。
デフォルトでは、参照のコピーを取得します: var copy = objectOfMyStruct;
. 明示的な浅いコピーを作成することを考えましたMemberwiseClone()
が、保護されたメソッドであり、変更できないため、これを行うことはできませんMyStruct
。
Convert.ChangeType(objectOfMyStruct, typeOfMyStruct)
内部で変換 (実際には変換なし) が発生し、オブジェクトが再び返されるため、役に立ちません。
どうすればこれを行うことができますか?
編集:
元の値を保持するためにコピーを作成し、それを逆シリアル化して 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でテストできるこの例では、実装されたインターフェイスを介した呼び出しによって変更されたときに、元の構造体のみが変更されるように、構造体のクローンを作成し、ボックス化されていない型にキャストし直す必要があります。したがって、問題は次のとおりです。その 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";
}
}