2016-11-25 12 views
1

Я начинаю с YAML и изучаю, как разбирать YAML в C#. Здесь я пытаюсь разобрать C# Object modules, где у меня есть данные о сложных типах объектов, таких как класс DataTable или Type, в C#. Я знаю, как преобразовать базовые типы с использованием библиотеки YAMLDotNet, но на самом деле не знаю, как сделать то же самое с такими типами. Пожалуйста, помогите.Преобразование сложных типов C# в YAML

ответ

0

A DataTable - сложный объект с потерянными свойствами. Самый простой способ - извлечь данные, которые относятся к вам, в более простую структуру данных и сериализовать это вместо этого. Тем не менее, если вы действительно этого хотите, вы можете создать пользовательский IYamlTypeConverter. Ниже приведен пример, который будет сериализовать имена стола столбцов и тип, а также значение строк:

public class DataTableTypeConverter : IYamlTypeConverter 
{ 
    public bool Accepts(Type type) 
    { 
     return typeof(DataTable).IsAssignableFrom(type); 
    } 

    public object ReadYaml(IParser parser, Type type) 
    { 
     var table = new DataTable(); 

     parser.Expect<MappingStart>(); 

     ReadColumns(parser, table); 
     ReadRows(parser, table); 

     parser.Expect<MappingEnd>(); 

     return table; 
    } 

    private static void ReadColumns(IParser parser, DataTable table) 
    { 
     var columns = parser.Expect<Scalar>(); 
     if (columns.Value != "columns") 
     { 
      throw new YamlException(columns.Start, columns.End, 
            "Expected a scalar named 'columns'"); 
     } 

     parser.Expect<MappingStart>(); 
     while (parser.Allow<MappingEnd>() == null) 
     { 
      var columnName = parser.Expect<Scalar>(); 
      var typeName = parser.Expect<Scalar>(); 

      table.Columns.Add(columnName.Value, Type.GetType(typeName.Value)); 
     } 
    } 

    private static void ReadRows(IParser parser, DataTable table) 
    { 
     var columns = parser.Expect<Scalar>(); 
     if (columns.Value != "rows") 
     { 
      throw new YamlException(columns.Start, columns.End, 
            "Expected a scalar named 'rows'"); 
     } 

     parser.Expect<SequenceStart>(); 
     while (parser.Allow<SequenceEnd>() == null) 
     { 
      var row = table.NewRow(); 

      var columnIndex = 0; 
      parser.Expect<SequenceStart>(); 
      while (parser.Allow<SequenceEnd>() == null) 
      { 
       var value = parser.Expect<Scalar>(); 
       var columnType = table.Columns[columnIndex].DataType; 
       row[columnIndex] = TypeConverter.ChangeType(value.Value, columnType); 
       ++columnIndex; 
      } 

      table.Rows.Add(row); 
     } 
    } 

    public void WriteYaml(IEmitter emitter, object value, Type type) 
    { 
     var table = (DataTable)value; 
     emitter.Emit(new MappingStart()); 

     EmitColumns(emitter, table); 
     EmitRows(emitter, table); 

     emitter.Emit(new MappingEnd()); 
    } 

    private static void EmitColumns(IEmitter emitter, DataTable table) 
    { 
     emitter.Emit(new Scalar("columns")); 
     emitter.Emit(new MappingStart(null, null, true, MappingStyle.Block)); 
     foreach (DataColumn column in table.Columns) 
     { 
      emitter.Emit(new Scalar(column.ColumnName)); 
      emitter.Emit(new Scalar(column.DataType.AssemblyQualifiedName)); 
     } 
     emitter.Emit(new MappingEnd()); 
    } 

    private static void EmitRows(IEmitter emitter, DataTable table) 
    { 
     emitter.Emit(new Scalar("rows")); 
     emitter.Emit(new SequenceStart(null, null, true, SequenceStyle.Block)); 

     foreach (DataRow row in table.Rows) 
     { 
      emitter.Emit(new SequenceStart(null, null, true, SequenceStyle.Flow)); 
      foreach (var item in row.ItemArray) 
      { 
       var value = TypeConverter.ChangeType<string>(item); 
       emitter.Emit(new Scalar(value)); 
      } 
      emitter.Emit(new SequenceEnd()); 
     } 

     emitter.Emit(new SequenceEnd()); 
    } 
} 

Он используется следующим образом:

var table = new DataTable(); 
table.Columns.Add("id", typeof(int)); 
table.Columns.Add("name", typeof(string)); 
table.Columns.Add("description", typeof(string)); 

table.Rows.Add(1, "first", "The first row"); 
table.Rows.Add(2, "second", "The second row"); 

// Serialize 
var serializer = new SerializerBuilder() 
    .WithTypeConverter(new DataTableTypeConverter()) 
    .Build(); 

var yaml = serializer.Serialize(table); 

// Deserialize 
var deserializer = new DeserializerBuilder() 
    .WithTypeConverter(new DataTableTypeConverter()) 
    .Build(); 

var parsedTable = deserializer.Deserialize<DataTable>(yaml); 

Сериализованный YAML в этом примере, :

columns: 
    id: System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
    name: System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
    description: System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
rows: 
- [1, first, The first row] 
- [2, second, The second row] 
+0

Спасибо :) Это сработало (y) – Anonymous

 Смежные вопросы

  • Нет связанных вопросов^_^