在C#中复制动态对象

5

我有一个问题,需要克隆动态对象,代码如下:

    public void Execute(IPrepareData entity)
    {
        try
        {                
            dynamic data = entity.Primary as dynamic;
            data.PreviousInfo = deepClone(data.Info);
        }
        catch (Exception ex)
        {
            data.Errors.Add(ex.Message);
        }
    }

    private static T deepClone<T>(T obj)
    {
        if (typeof(T).IsClass || typeof(T).IsArray)
        {
            if (ReferenceEquals(obj, null))
            {
                return default(T);
            }
        }
        using (var memoryStream = new MemoryStream())
        {
            BinaryFormatter fieldFormatter = new BinaryFormatter();
            fieldFormatter.Serialize(memoryStream, obj);
            memoryStream.Position = 0;
            return (T)fieldFormatter.Deserialize(memoryStream);
        }
    }

    dynamic data;

我不知道实体的结构(只知道它将包含信息,而且我不知道信息的结构),并且它不会被标记为可序列化。我需要将此信息复制到实体的先前信息部分。
执行此代码的结果是“对象引用未设置为对象的实例”在fieldFormatter.Serialize行上。
如何检查它是否是对象的实例?
可能会有(很可能会有)循环引用,因此我不会尝试反射,因为我不确定如何处理它。另外,速度不是问题。

2
data.Infonull。这就是为什么你会收到异常的原因。 - Daniel Hilgarth
如果通过了 if(ReferenceEquals(obj, null)) 检查,那么它是如何传递的呢? - Sergei G
有趣。typeof(T)typeof(T).IsClass是什么? - Daniel Hilgarth
typeof(T).IsClass为true,Name =“Info”,FullName =“Project.Entities.Info”,因此它通过了检查。 - Sergei G
3个回答

8

关于什么?

var clone = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(obj));

5
如果你不知道数据将被标记为可序列化,那么就不能依赖于使用 BinaryFormatter。
如果对象可能具有循环引用,许多其他序列化程序都不适用。
如果我们假设它是 dynamic 的一般情况(而不仅仅是 ExpandoObject),那么没有办法获取关于成员的信息,因为它们可以在查询时被发明。
基本上,这种情况没有好答案。没有魔法方法来深度克隆“一个东西”。

0

我一直在使用JSON.net来序列化用户定义的类型,效果很好。

有一些标志可以忽略空属性,否则默认会保存为

{propname: 'undefined'}

我知道你提到速度不是问题,但序列化器非常快。

这里是NuGet包


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接