.NET Core中[Serializable]的等价物是什么? (转换项目)

时间:2016-08-29 05:31:06

标签: c# .net-core

在许多情况下,当我想将当前的.NET Framework项目转换为.NET Core等效项时,某些类具有 Serializable属性

如何在.NET Core中转换它们? (在这个时候我删除了它们!)

修改

考虑以下代码:

using System;

namespace DotLiquid.Exceptions
{
    [Serializable] // I delete it now !!!!!!!
    public class FilterNotFoundException : Exception
    {
        public FilterNotFoundException(string message, FilterNotFoundException innerException)
            : base(message, innerException)
        {
        }

        public FilterNotFoundException(string message, params string[] args)
            : base(string.Format(message, args))
        {
        }

        public FilterNotFoundException(string message)
            : base(message)
        {
        }
    }
}

上面没有[Serializable]的代码在.NET Core中工作,没有语法问题。

但我想知道何时删除[Serializable]

什么是副作用?

应该更改哪些地方?

我应该何时使用JSON.NET(或...)代替[Serializable]?

4 个答案:

答案 0 :(得分:20)

更新此处的问题。

Microsoft似乎已将SerializeAttribute移植到单独的nuget包中:System.Runtime.Serialization.Formatters

您可以使用此nuget包。虽然我不知道为什么他们以后加了它。

他们删除了它,因为它们也删除了二进制序列化,它主要用于此。也许他们仍然把它带回来为其他类型的序列化创建基础(如json,xml等)。因为它们仍然需要相同的基础(至少是json):你不能使用接口或抽象属性,因为de deserializer不知道要为这个属性创建哪个对象。

也许有人可以对这种情况有所了解,或者当我知道更多时,我会这样做。

什么是SerializeableAttribute(origin)

这个想法是你把这个属性放在一个类上,告诉它是可序列化的,意思是:

  • 对象'无法'拥有子类
  • 对象桅杆上的属性是具体类(因此没有抽象类或接口)

为什么?

因为在反序列化时反映了类及其属性,如果反射会找到一个接口作为属性,它就不知道要创建哪个子类(右边的dll甚至可能都没有被加载,像这样的问题)。

所以在代码中:

public class NotSerializableObject {
    public IEnumerable<Test> property {get; set;}
}
public interface AlsoNotSerializableObject {
    List<Test> property {get; set;}
}
public class SerializableObject {
    public List<Test> property {get; set;}
}

为什么'弃用'

此属性和二进制格式化程序本身存在许多问题(实际检查此属性的唯一(de)序列化程序)。

属性问题:在编译期间无法强制执行,因此只有在运行时才会出现错误,首先:错误,您忘记了SerializableAttribute。并且只有在运行时稍后才会出现错误您无法使用IEnumerable,因为它是一个接口。因此,它只能创造额外的工作,而不是解决任何问题。

他们没有使用二进制格式化迁移它,因为他们认为它已经被删除了,或者“必须重做”那里有一些主要问题(他们在他们的一个视频会话/ confs中说过这样的事情)。

我到目前为止与IPC结合发现的唯一问题是,在DateTime对象上,Kind属性未被(de)序列化。

但它又回到了这个nuget包中:https://www.nuget.org/packages/BinaryFormatter/

似乎他们甚至推出了一个新版本(2.1.0),这可能表明他们想要延长其活跃时间。

他们为什么迁移它?

他们试图将人们带到新的'Dotnet Core'(而不是完整的框架)。他们使用的策略之一是移植所有内容,即使他们认为代码很糟糕,也不应该被任何人/“更好的开源替代品”使用,这样人们就可以更容易地迁移他们的旧代码。

1缺点是很难找到关于什么nuget-packages / dll应该被认为是“糟糕”的正确信息以及哪些nuget包从哪里彻底重做并建议再次使用。

答案 1 :(得分:10)

如果您没有序列化该类型(即使用BinaryFormatter),那么您可以删除[Serializable]并忘掉它。

如果你以前使用BinaryFormatter进行序列化,那么你需要提出自己的计划,看看它是如何工作的(即通过Json.net或XML)。

如果您要移植图书馆并代表您的消费者提问,那么答案是相同的:删除[Serializable]并将序列化保留给需要它的人。

答案 2 :(得分:9)

由于序列化中涉及的复杂性和兼容性问题,已从.Net Core中删除了二进制序列化。相反,决定序列化应该是基于协议的。请参阅:https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/porting.md#binary-serialization

这确实不会影响大多数用例,因为您可以使用XML Serializer或第三方软件包,如json.net

答案 3 :(得分:4)

更新到给定答案:

.Net Core 2.0 现在支持类型子集的二进制序列化,您可以看到完整列表here