From 2a1cd4fda8a4a8e649910d16b4dfa1ce7ae63543 Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Fri, 12 May 2023 09:24:40 +0800 Subject: *misc --- .../CsvHelper/Expressions/DynamicRecordWriter.cs | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/DynamicRecordWriter.cs (limited to 'ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/DynamicRecordWriter.cs') diff --git a/ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/DynamicRecordWriter.cs b/ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/DynamicRecordWriter.cs new file mode 100644 index 0000000..a9ee401 --- /dev/null +++ b/ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/DynamicRecordWriter.cs @@ -0,0 +1,75 @@ +// Copyright 2009-2022 Josh Close +// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0. +// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0. +// https://github.com/JoshClose/CsvHelper +using Microsoft.CSharp.RuntimeBinder; +using System; +using System.Collections; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; + +namespace CsvHelper.Expressions +{ + /// + /// Write dynamic records. + /// + public class DynamicRecordWriter : RecordWriter + { + private readonly Hashtable getters = new Hashtable(); + + /// + /// Initializes a new instance using the given writer. + /// + /// The writer. + public DynamicRecordWriter(CsvWriter writer) : base(writer) { } + + /// + /// Creates a of type + /// that will write the given record using the current writer row. + /// + /// The record type. + /// The record. + protected override Action CreateWriteDelegate(T record) + { + // http://stackoverflow.com/a/14011692/68499 + + Action action = r => + { + var provider = (IDynamicMetaObjectProvider)r; + var type = provider.GetType(); + + var parameterExpression = Expression.Parameter(typeof(T), "record"); + var metaObject = provider.GetMetaObject(parameterExpression); + var memberNames = metaObject.GetDynamicMemberNames(); + if (Writer.Configuration.DynamicPropertySort != null) + { + memberNames = memberNames.OrderBy(name => name, Writer.Configuration.DynamicPropertySort); + } + + foreach (var name in memberNames) + { + var value = GetValue(name, provider); + Writer.WriteField(value); + } + }; + + return action; + } + + private object GetValue(string name, IDynamicMetaObjectProvider target) + { + // https://stackoverflow.com/a/30757547/68499 + + var callSite = (CallSite>)getters[name]; + if (callSite == null) + { + var getMemberBinder = Binder.GetMember(CSharpBinderFlags.None, name, typeof(DynamicRecordWriter), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }); + getters[name] = callSite = CallSite>.Create(getMemberBinder); + } + + return callSite.Target(callSite, target); + } + } +} \ No newline at end of file -- cgit v1.1-26-g67d0