// 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 System; using System.Collections.Generic; using System.Reflection; namespace CsvHelper.Expressions { /// /// Base implementation for classes that create records. /// public abstract class RecordCreator { private readonly Dictionary createRecordFuncs = new Dictionary(); /// /// The reader. /// protected CsvReader Reader { get; private set; } /// /// The expression manager. /// protected ExpressionManager ExpressionManager { get; private set; } /// /// Initializes a new instance using the given reader. /// /// The reader. public RecordCreator(CsvReader reader) { Reader = reader; ExpressionManager = new ExpressionManager(reader); } /// /// Create a record of the given type using the current row. /// /// The record type. public T Create() { try { return ((Func)GetCreateRecordDelegate(typeof(T))).Invoke(); } catch (TargetInvocationException ex) { if (ex.InnerException != null) { throw ex.InnerException; } else { throw; } } } /// /// Create a record of the given type using the current row. /// /// The record type. public object? Create(Type recordType) { try { return GetCreateRecordDelegate(recordType).DynamicInvoke(); } catch (TargetInvocationException ex) { if (ex.InnerException != null) { throw ex.InnerException; } else { throw; } } } /// /// Gets the delegate to create a record for the given record type. /// If the delegate doesn't exist, one will be created and cached. /// /// The record type. protected virtual Delegate GetCreateRecordDelegate(Type recordType) { if (!createRecordFuncs.TryGetValue(recordType, out Delegate func)) { createRecordFuncs[recordType] = func = CreateCreateRecordDelegate(recordType); } return func; } /// /// Creates a of type /// that will create a record of the given type using the current /// reader row. /// /// The record type. protected abstract Delegate CreateCreateRecordDelegate(Type recordType); } }