How to clone an ExpandoObject

This is for the MVVM-based WPF project:

I use ExpandoObjectthe view model for a dialog that works very well, since it implements INotifyPropertyChanged, and I can bind to the properties of the object directly in XAML.

However, to account for user manipulations with data, but then with deletion, I need to make a copy ExpandoObjectto restore the original content.

In the dialog box, no properties are added to the object.

How can I clone it?

+4
source share
3 answers

As a remaining proponent of static typing, eugh ...

As they say, it looks like it ExpandoObjectimplements IDictionary<string, object>:

dynamic foo1d = new ExpandoObject();
foo1d.a = "test";

dynamic foo2d = new ExpandoObject();
foreach (var kvp in (IDictionary<string, object>)foo1d)
{
    ((IDictionary<string, object>)foo2d).Add(kvp);
}

Debug.Assert(foo1d.a == foo2d.a);

VB:

Dim foo1d As Object = New ExpandoObject
Dim foo2d As Object = New ExpandoObject
foo1d.a = "foo"

Dim cloneDictionary = CType(foo2d, IDictionary(Of String, Object))
For Each line In CType(foo1d, IDictionary(Of String, Object))
    cloneDictionary.Add(line.Key, line.Value)
Next

, . , , .

+9

:

static ExpandoObject ShallowCopy(ExpandoObject original)
{
    var clone = new ExpandoObject();

    var _original = (IDictionary<string, object>)original;
    var _clone = (IDictionary<string, object>)clone;

    foreach (var kvp in _original)
        _clone.Add(kvp);

    return clone;
}

:

static ExpandoObject DeepCopy(ExpandoObject original)
{
    var clone = new ExpandoObject();

    var _original = (IDictionary<string, object>)original;
    var _clone = (IDictionary<string, object>)clone;

    foreach (var kvp in _original)
        _clone.Add(kvp.Key, kvp.Value is ExpandoObject ? DeepCopy((ExpandoObject)kvp.Value) : kvp.Value);

    return clone;
}
+3
var ExpandoObjs = GetDynamicList();
//clone
var clonedExpandos = ExpandoObjs.Cast<dynamic>().Select(x => x).ToList();
//modify and sort
var transformedExpandos = ExpandoObjs.Cast<dynamic>().Select(x =>
{
    x.url= x.url + " some more stuff";
    return x;
}).OrderBy(x => x.order).ToList();

url , .

This is useful if you are using a service call that does not have specific types and you want to change / sort the result.

-2
source

Source: https://habr.com/ru/post/1534751/


All Articles