【问题标题】:YamlDotNet change property name according to valueYamlDotNet 根据值更改属性名称
【发布时间】:2021-01-18 18:00:49
【问题描述】:

我正在尝试根据我在 yaml 文件的输出中获得的值来格式化对象的属性名称。我正在使用 yamldotnet 库。以下是我的课程

State.cs

public class State
    {
        public string name { get; set; }
        public List<Operation> operations { get; set; }

    }

Operation.cs

public class Operation
    {
        public string name { get; set; }
        public string type { get; set; }
    }

在状态类中,我有操作列表。序列化后,我得到以下 yaml 输出:

states:
- name: uPError
  operations:
  - name: switch on uP
    type: entry
  - name: switch off uP
    type: exit
  - name: test Do
    type: do

但我打算显示的格式如下:

states:
- name: uPError
  entryActions: [switch on uP]
  exitActions: [switch off uP]
  doActions: [test Do]

我正在获取类型及其名称,根据类型,我需要将其更改为 entryActionexitActionsdoActions 和然后附加相应的名称。如何实现上述预期格式?提前致谢。

【问题讨论】:

    标签: c# .net yaml yamldotnet


    【解决方案1】:

    实现这一点的一种方法是实现IYamlTypeConverter 来自定义State 类型的转换。这使您可以控制类的整个序列化:

    public class StateConverter : IYamlTypeConverter
    {
        public bool Accepts(Type type)
        {
            return type == typeof(State);
        }
    
        public object? ReadYaml(IParser parser, Type type)
        {
            var state = new State { operations = new List<UserQuery.Operation>() };
            
            parser.Consume<MappingStart>();
            while (!parser.TryConsume<MappingEnd>(out var _))
            {
                var key = parser.Consume<Scalar>().Value;
                if (key == nameof(state.name))
                {
                    state.name = parser.Consume<Scalar>().Value;
                }
                else
                {
                    parser.Consume<SequenceStart>();
                    while (!parser.TryConsume<SequenceEnd>(out var _))
                    {
                        state.operations.Add(new Operation
                        {
                           type = key,
                           name = parser.Consume<Scalar>().Value,
                        });
                    }
                }
            }
            
            return state;
        }
    
        public void WriteYaml(IEmitter emitter, object? value, Type type)
        {
            var state = (State)value!;
            
            emitter.Emit(new MappingStart());
            
            emitter.Emit(new Scalar(nameof(state.name)));
            emitter.Emit(new Scalar(state.name));
    
            foreach (var operationGroup in state.operations.GroupBy(o => o.type))
            {
                emitter.Emit(new Scalar(operationGroup.Key));
    
                emitter.Emit(new SequenceStart(null, null, false, SequenceStyle.Flow));
                foreach (var operation in operationGroup)
                {
                    emitter.Emit(new Scalar(operation.name));
                }
                emitter.Emit(new SequenceEnd());
            }
    
            emitter.Emit(new MappingEnd());
        }
    }
    

    您需要在SerializerBuilderDeserializerBuilder 上注册该类型:

    var serializer = new SerializerBuilder()
        .WithTypeConverter(new StateConverter())
        .Build();
    
    var deserializer = new DeserializerBuilder()
        .WithTypeConverter(new StateConverter())
        .Build();
    

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2012-01-18
      • 2017-01-31
      • 2021-10-10
      相关资源
      最近更新 更多