/// <summary> /// Initialisiert ein <see cref="CsvRecord"/>-Objekt mit Standardnamen für die Spalten ("Column1", "Column2" etc). (Geeignet für /// CSV-Dateien ohne Kopfzeile.) /// </summary> /// <param name="columnsCount">Anzahl der Spalten.</param> /// <param name="caseSensitive">Wenn <c>true</c>, werden die Spaltennamen case-sensitiv behandelt.</param> /// <param name="initArr">Wenn <c>false</c>, wird das Datenarray nicht initialisiert. Das Objekt taugt dann nur als Kopierschablone /// für weitere <see cref="CsvRecord"/>-Objekte. (Wird von <see cref="CsvReader"/> verwendet.)</param> internal CsvRecord(int columnsCount, bool caseSensitive, bool initArr) { IEqualityComparer <string> comparer = caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; this._lookupDictionary = new Dictionary <string, int>(columnsCount, comparer); var keyArr = new string[columnsCount]; for (int i = 0; i < columnsCount; i++) { string keyName = AutoColumnName.Create(i); keyArr[i] = keyName; this._lookupDictionary.Add(keyName, i); } this._columnNames = new ReadOnlyCollection <string>(keyArr); if (initArr) { _values = new string?[columnsCount]; } }
/// <summary> /// Initialisiert ein neues <see cref="CsvIndexProperty"/>-Objekt. /// </summary> /// <param name="propertyName">Der Bezeichner unter dem die Eigenschaft angesprochen wird. Er muss den Regeln für C#-Bezeichner /// entsprechen. Es werden nur ASCII-Zeichen akzeptiert.</param> /// <param name="csvColumnIndex">Nullbasierter Index der Spalte der CSV-Datei.</param> /// <param name="converter">Der <see cref="ICsvTypeConverter"/>, der die Typkonvertierung übernimmt.</param> /// /// <exception cref="ArgumentException"><paramref name="propertyName"/> entspricht nicht den Regeln für C#-Bezeichner (nur /// ASCII-Zeichen).</exception> /// /// <exception cref="ArgumentNullException"><paramref name="propertyName"/> oder /// <paramref name="converter"/> ist <c>null</c>.</exception> /// /// <exception cref="ArgumentOutOfRangeException"><paramref name="csvColumnIndex"/> ist kleiner als 0.</exception> public CsvIndexProperty( string propertyName, int csvColumnIndex, ICsvTypeConverter converter) : base(propertyName, new string[] { AutoColumnName.Create(csvColumnIndex) }, converter) { if (csvColumnIndex < 0) { throw new ArgumentOutOfRangeException(nameof(csvColumnIndex)); } }
/// <summary> /// Initialisiert ein neues <see cref="CsvRecord"/>-Objekt mit Spaltennamen. (Geeignet für /// CSV-Dateien mit Kopfzeile.) /// </summary> /// <param name="keys">Spaltennamen. Die Auflistung kann <c>null</c>-Werte enthalten: Diese werden dann durch /// Standardnamen ersetzt.</param> /// <param name="caseSensitive">Wenn <c>true</c>, werden die Spaltennamen case-sensitiv behandelt.</param> /// <param name="trimColumns">Wenn <c>true</c>, werden alle Spaltennamen mit der Methode <see cref="string.Trim()"/> behandelt.</param> /// <param name="initArr">Wenn <c>false</c>, wird das Datenarray nicht initialisiert. Das Objekt taugt dann nur als Kopierschablone /// für weitere <see cref="CsvRecord"/>-Objekte. (Wird von <see cref="CsvReader"/> verwendet.</param> /// <param name="throwException">Wenn <c>true</c>, wird eine <see cref="ArgumentException"/> geworfen, /// wenn <paramref name="keys"/> 2 identische Spaltennamen enthält. Beim Lesen einer Datei sollte der /// Parameter auf <c>false</c> gesetzt werden, um die Spaltennamen automatisch so abzuwandeln, dass sie eindeutig sind.</param> /// <exception cref="ArgumentException">Ein Spaltenname war bereits im Dictionary enthalten. Die Exception wird nur dann /// geworfen, wenn <paramref name="throwException"/> <c>true</c> ist.</exception> internal CsvRecord(string?[] keys, bool caseSensitive, bool trimColumns, bool initArr, bool throwException) { Debug.Assert(keys != null); IEqualityComparer <string> comparer = caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; this._lookupDictionary = new Dictionary <string, int>(keys.Length, comparer); int defaultNameCounter = 0; for (int i = 0; i < keys.Length; i++) { string?key = keys[i]; if (key is null) { key = GetDefaultName(); _lookupDictionary.Add(key, i); keys[i] = key; continue; } if (trimColumns) { key = key.Trim(); } if (!throwException && _lookupDictionary.ContainsKey(key)) { key = MakeUnique(key); } _lookupDictionary.Add(key, i); keys[i] = key; } this._columnNames = new ReadOnlyCollection <string>(keys !); if (initArr) { _values = new string?[Count]; } /////////////////////////////////////////////////// string GetDefaultName() { string key; do { key = AutoColumnName.Create(defaultNameCounter++); } while (_lookupDictionary.ContainsKey(key)); return(key); } ////////////////////////////////////////////////////// string MakeUnique(string key) { string unique; int cnt = 1; do { unique = key + (++cnt).ToString(CultureInfo.InvariantCulture); } while (_lookupDictionary.ContainsKey(unique)); return(unique); } }