首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何跳过Yamldotnet中的空藏品

如何跳过Yamldotnet中的空藏品
EN

Stack Overflow用户
提问于 2019-06-02 00:11:42
回答 3查看 1.5K关注 0票数 3

我试图找出如何跳过使用YamlDotNet序列化空集合。我已经尝试过定制的ChainedObjectGraphVisitor和IYamlTypeConverter。我刚开始使用YamlDotNet,这里有一些知识空白。

下面是我对访问者模式的实现,它导致了YamlDotNet.Core.YamlException “预期的标量、序列启动、映射-开始或别名,got”错误。我确实看到了一些MappingStart/MappingEnd的在线内容,但我不知道它如何适合我所要做的工作(消除大量空集合中的杂乱)。任何指向正确方向的指针都会受到赞赏。

实例化序列化程序:

代码语言:javascript
复制
var serializer = new YamlDotNet.Serialization.SerializerBuilder()
                .WithNamingConvention(new YamlDotNet.Serialization.NamingConventions.CamelCaseNamingConvention())
                .WithEmissionPhaseObjectGraphVisitor(args => new YamlIEnumerableSkipEmptyObjectGraphVisitor(args.InnerVisitor))
                .Build();

ChainedObjectGraphVisitor实现:

代码语言:javascript
复制
    public sealed class YamlIEnumerableSkipEmptyObjectGraphVisitor : ChainedObjectGraphVisitor
{
    public YamlIEnumerableSkipEmptyObjectGraphVisitor(IObjectGraphVisitor<IEmitter> nextVisitor)
        : base(nextVisitor)
    {
    }

    public override bool Enter(IObjectDescriptor value, IEmitter context)
    {
        bool retVal;

        if (typeof(System.Collections.IEnumerable).IsAssignableFrom(value.Value.GetType()))
        {   // We have a collection
            var enumerableObject = (System.Collections.IEnumerable)value.Value;
            if (enumerableObject.GetEnumerator().MoveNext()) // Returns true if the collection is not empty.
            {   // Serialize it as normal.
                retVal = base.Enter(value, context);
            }
            else
            {   // Skip this item.
                retVal = false;
            }
        }
        else
        {   // Not a collection, normal serialization.
            retVal = base.Enter(value, context);
        }

        return retVal;
    }
}
EN

回答 3

Stack Overflow用户

发布于 2019-06-02 16:08:01

我相信答案也是用类似于Enter()方法中所做的逻辑覆盖基类中的EnterMapping()方法:

代码语言:javascript
复制
public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context)
{
    bool retVal = false;

    if (value.Value == null)
        return retVal;

    if (typeof(System.Collections.IEnumerable).IsAssignableFrom(value.Value.GetType()))
    {   // We have a collection
        var enumerableObject = (System.Collections.IEnumerable)value.Value;
        if (enumerableObject.GetEnumerator().MoveNext()) // Returns true if the collection is not empty.
        {   // Don't skip this item - serialize it as normal.
            retVal = base.EnterMapping(key, value, context);
        }
        // Else we have an empty collection and the initialized return value of false is correct.
    }
    else
    {   // Not a collection, normal serialization.
        retVal = base.EnterMapping(key, value, context);
    }

    return retVal;
}
票数 3
EN

Stack Overflow用户

发布于 2020-11-08 10:47:10

最后,我上了下面的课:

代码语言:javascript
复制
using System.Collections;
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.ObjectGraphVisitors;

sealed class YamlIEnumerableSkipEmptyObjectGraphVisitor : ChainedObjectGraphVisitor
{
    public YamlIEnumerableSkipEmptyObjectGraphVisitor(IObjectGraphVisitor<IEmitter> nextVisitor): base(nextVisitor)
    {
    }

    private bool IsEmptyCollection(IObjectDescriptor value)
    {
        if (value.Value == null)
            return true;

        if (typeof(IEnumerable).IsAssignableFrom(value.Value.GetType()))
            return !((IEnumerable)value.Value).GetEnumerator().MoveNext();

        return false;
    }

    public override bool Enter(IObjectDescriptor value, IEmitter context)
    {
        if (IsEmptyCollection(value))
            return false;

        return base.Enter(value, context);
    }

    public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context)
    {
        if (IsEmptyCollection(value))
            return false;

        return base.EnterMapping(key, value, context);
    }
}
票数 2
EN

Stack Overflow用户

发布于 2022-09-29 08:57:30

您可以指定DefaultValuesHandling

在序列化程序中:

代码语言:javascript
复制
var serializer = new SerializerBuilder()
    .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitEmptyCollections)
    .Build();   

或在字段/属性的属性YamlMember中:

代码语言:javascript
复制
public class MyDtoClass
{

    [YamlMember(DefaultValuesHandling = DefaultValuesHandling.OmitEmptyCollections)]
    public List<string> MyCollection;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56411304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档