使用重写的Equals方法

时间:2018-05-05 18:27:34

标签: c# json.net

尝试使用重载的Equals(object obj)方法序列化自定义类型的集合。我正在使用Newtonsoft.Json.JsonConvert.SerializeObject(object value)来实现这一目标。

这是我的抽象基本视图模型,有问题的视图模型从该模型继承:

public abstract class BaseCollectibleViewModel
{
    protected abstract bool CompareParameters(object item);

    protected abstract List<int> GetParameters();

    public override bool Equals(object obj)
    {
        if (CompareParameters(obj))
        {
            return true;
        }
        return false;
    }

    public override int GetHashCode()
    {
        int hash = 13;
        foreach (var parameter in GetParameters())
        {
            hash = (hash * 7) + parameter.GetHashCode();
        }

        return hash;
    }

    public static bool operator ==(BaseCollectibleViewModel a, BaseCollectibleViewModel b)
    {
        if (a.Equals(b))
        {
            return true;
        }
        return false;
    }

    public static bool operator !=(BaseCollectibleViewModel a, BaseCollectibleViewModel b)
    {
        if (a.Equals(b))
        {
            return false;
        }
        return true;
    }
}

这是实际的视图模型:

public class ImagesViewModel : BaseCollectibleViewModel, ISourceImage
{
    public string Name { get; private set; }
    public string Type { get; private set; }
    [ScriptIgnore]
    public Stream Content { get; private set; }
    [ScriptIgnore]
    private HttpPostedFileBase _file;
    [ScriptIgnore]
    public HttpPostedFileBase File
    {
        get
        {
            return _file;
        }
        set
        {
            _file = value;
            Name = File.FileName;
            Type = File.ContentType;
            Content = new MemoryStream();
            File.InputStream.CopyTo(Content);
        }
    }

    protected override bool CompareParameters(object obj)
    {
        var temp = obj as ImagesViewModel;
        if(temp == null)
        {
            return false;
        }
        return
            (Name == temp.Name &&
            Type == temp.Type);
    }

    protected override List<int> GetParameters()
    {
        return new List<int>()
        {
            Name.GetHashCode(),
            Type.GetHashCode()
        };
    }
}

请注意ScriptIgnore属性。我甚至在私人领域有一个。该程序在基类的==运算符上中断,因为传递的两个参数都为null。

这是序列化代码:

[HttpPost]
public string GetSessionImages()
{
    var imagesInSession = _imagesSessionService.GetCollection();
    return JsonConvert.SerializeObject(imagesInSession, Formatting.Indented);
}

另外这个: enter image description here

屏幕截图显示了继承视图模型上抽象CompareParameters(object obj)方法的实现。该流是Content属性流,我已经检查过了。为什么会这样?

编辑:当没有覆盖等于时,我得到一个JsonSerializationException陈述:

  

{“从'ReadTimeout'获取值时出错   'System.IO.MemoryStream'。“}

编辑2:根据dbc的评论我已将[ScriptIgnore]替换为[JsonIgnore],并且代码在一定程度上起作用。 但是,我必须注释掉运算符实现,因为'=='运算符将作为null参数传递BaseCollectibleViewModel b值。

1 个答案:

答案 0 :(得分:1)

由于您使用的是,因此您必须使用[JsonIgnore]将成员标记为忽略:

using Newtonsoft.Json;

public class ImagesViewModel : BaseCollectibleViewModel, ISourceImage
{
    public string Name { get; private set; }
    public string Type { get; private set; }

    [ScriptIgnore]
    [JsonIgnore]
    public Stream Content { get; private set; }

    [ScriptIgnore]
    [JsonIgnore]
    public HttpPostedFileBase File { get { ... } set { ... } }

没有必要使用[JsonIgnore]标记完全私有成员,因为Json.NET默认不对这些成员进行序列化。

或者,如果您不希望模型依赖于Json.NET,则可以使用conditional property serialization无条件地禁止使用相同的成员:

public class ImagesViewModel : BaseCollectibleViewModel, ISourceImage
{
    public string Name { get; private set; }
    public string Type { get; private set; }

    [ScriptIgnore]
    public Stream Content { get; private set; }

    public bool ShouldSerializeContent() { return false; }

    [ScriptIgnore]
    public HttpPostedFileBase File { get { ... } set { ... } }

    public bool ShouldSerializeFile() { return false; }

请注意,其他序列化程序(包括XmlSerializer)也会尊重ShouldSerializeXXX()条件序列化模式,如 ShouldSerialize*() vs *Specified Conditional Serialization Pattern 中所述 - 副作用可能是是否合意。

(顺便提一下,您可能需要检查一下,如 JSON.NET Parser *seems* to be double serializing my objects 所示,您没有对数据进行双重序列化。)