Как я могу применить скалярный стиль YamlDotNet.Одинарная ссылка на свойство string в списке?

#c# #yaml #yamldotnet

#c# #ямл #yamldotnet

Вопрос:

Я использую YamlDotNet для сериализации объекта, подобного этому

 using System.Collections.Generic; using YamlDotNet.Core; using YamlDotNet.Serialization;  public class Thing {  [YamlMember(ScalarStyle = ScalarStyle.SingleQuoted)]  public string Name   [YamlMember(ScalarStyle = ScalarStyle.SingleQuoted)]  public Listlt;stringgt; Attributes }  

Я успешно сериализую свойство простой строки, как и ожидалось

 using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions;  var myObject = new Thing {  Name = "foo"  Attributes = new Listlt;stringgt;() { "bar" } };  var ymlSerializer = new SerializerBuilder()  .WithNamingConvention(CamelCaseNamingConvention.Instance)  .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitEmptyCollections | DefaultValuesHandling.OmitNull)  .Build();  var serializedYaml = ymlSerializer.Serialize(myObject);  

Производит yaml:

 name: 'foo' attributes: - bar  

Ожидаемый yaml:

 name: 'foo' attributes: - 'bar'  

Как я могу применить атрибут скалярного стиля к списку примитива?

Ответ №1:

вы должны использовать пользовательский конвертер:

пользовательский конвертер классов:

 public class ThingCategoryYamlTypeConverter : IYamlTypeConverter  {  private void WriteContentCategory(IEmitter emitter, object value)  {  Thing node;  node = (Thing)value;   emitter.Emit(new MappingStart(null, null, false, MappingStyle.Block));   if (node.Name != null)  {  emitter.Emit(new Scalar(null, "name"));  emitter.Emit(new Scalar(null, null, node.Name, ScalarStyle.SingleQuoted, true, false));  }   if (node.Attributes != null)  {  this.WriteAttributes(emitter, node);  }   emitter.Emit(new MappingEnd());  }   private void WriteAttributes(IEmitter emitter, Thing node)  {  emitter.Emit(new Scalar(null, "attributes"));  emitter.Emit(new SequenceStart(null, null, false, SequenceStyle.Block));   foreach (string child in node.Attributes)  {  emitter.Emit(new Scalar(null, null, child, ScalarStyle.SingleQuoted, true, false ));  }   emitter.Emit(new SequenceEnd());  }   public bool Accepts(Type type)  {  return type == typeof(Thing);  }   public object ReadYaml(IParser parser, Type type)  {  // use for deserialization  throw new NotImplementedException();  }   public void WriteYaml(IEmitter emitter, object value, Type type)  {  this.WriteContentCategory(emitter, value);  }  }  

ваш класс:

 public class Thing  {  public string Name;   public Listlt;stringgt; Attributes;  }  

вызовите пользовательский конвертер

 static void Main(string[] args)  {  var myObject = new Thing  {  Name = "foo",  Attributes = new Listlt;stringgt; { "bar" }  };   var ymlSerializer = new SerializerBuilder()  .WithTypeConverter(new ThingCategoryYamlTypeConverter())  .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitEmptyCollections | DefaultValuesHandling.OmitNull)  .Build();   var serializedYaml = ymlSerializer.Serialize(myObject);   }  

Результат:

 name: 'foo' attributes: - 'bar'