/// <summary> /// Gibt eine Sammlung von <see cref="VCard"/>-Objekten zurück, in der die <see cref="RelationVCardProperty"/>-Objekte /// der als Argument übergebenen /// Sammlung von <see cref="VCard"/>-Objekten durch /// <see cref="RelationUuidProperty"/>-Objekte ersetzt sind und in der die in den /// <see cref="RelationVCardProperty"/>-Objekten referenzierten <see cref="VCard"/>-Objekte als /// separate Elemente angefügt sind. /// </summary> /// /// <param name="vCards">Sammlung von <see cref="VCard"/>-Objekten. Die Auflistung darf leer sein und <c>null</c>-Werte /// enthalten.</param> /// /// <returns> /// Eine Sammlung von <see cref="VCard"/>-Objekten, in der die <see cref="RelationVCardProperty"/>-Objekte /// der als Argument übergebenen /// Sammlung von <see cref="VCard"/>-Objekten durch /// <see cref="RelationUuidProperty"/>-Objekte ersetzt sind und in der die in den /// <see cref="RelationVCardProperty"/>-Objekten referenzierten <see cref="VCard"/>-Objekte als /// separate Elemente angefügt sind. (Wenn die angefügten <see cref="VCard"/>-Objekte noch keine /// <see cref="VCard.UniqueIdentifier"/>-Eigenschaft hatten, wird ihnen /// von der Methode automatisch eine neue zugewiesen.) /// </returns> /// /// <remarks> /// <note type="caution"> /// Obwohl die Methode selbst threadsafe ist, sind es die an die Methode übergebenen /// <see cref="VCard"/>-Objekte nicht. Sperren Sie den lesenden und schreibenden Zugriff auf diese /// <see cref="VCard"/>-Objekte während der Ausführung dieser Methode! /// </note> /// <note type="important"> /// Verwenden Sie diese Methode niemals, wenn Sie eine VCF-Datei als vCard 2.1 oder vCard 3.0 speichern möchten. Es droht Datenverlust. /// </note> /// <note type="tip"> /// Sie können der Methode auch ein einzelnes <see cref="VCard"/>-Objekt übergeben, da die <see cref="VCard"/>-Klasse /// <see cref="IEnumerable{T}">IEnumerable<VCard></see> explizit implementiert. /// </note> /// <para> /// Die Methode wird bei Bedarf von den Serialisierungsmethoden von <see cref="VCard"/> automatisch verwendet. Die Verwendung in eigenem /// Code ist /// nur dann sinnvoll, wenn ein <see cref="VCard"/>-Objekt als vCard 4.0 gespeichert werden soll und wenn dabei jede VCF-Datei nur /// eine einzige vCard enthalten soll. (Dieses Vorgehen ist i.d.R. nicht vorteilhaft, da es die referentielle Integrität gefährdet.) /// </para> /// </remarks> /// /// <example> /// <para> /// Das Beispiel demonstriert, wie ein <see cref="VCard"/>-Objekt als vCard 4.0 gespeichert werden kann, wenn beabsichtigt ist, /// dass eine VCF-Datei jeweils nur eine einzige vCard enthalten soll. Das Beispiel zeigt möglicherweise auch, dass dieses Vorgehen i.d.R. /// nicht vorteilhaft ist, da es die referentielle Integrität gefährdet. /// </para> /// <para>In dem Beispiel wird die Erweiterungsmethode <see cref="VCardCollectionExtension.ReferenceVCards"/> verwendet, die /// <see cref="Reference(IEnumerable{VCard})"/> /// aufruft.</para> /// <note type="note">Der leichteren Lesbarkeit wegen, wurde in dem Beispiel auf Ausnahmebehandlung verzichtet.</note> /// <code language="cs" source="..\Examples\VCard40Example.cs"/> /// </example> /// /// <exception cref="ArgumentNullException"><paramref name="vCards"/> ist <c>null</c>.</exception> public static IEnumerable <VCard> Reference(IEnumerable <VCard?> vCards) { if (vCards is null) { throw new ArgumentNullException(nameof(vCards)); } List <VCard> list = vCards.Where(x => x is not null).ToList() !; for (int i = list.Count - 1; i >= 0; i--) { VCard vcard = list[i]; if (vcard.Members != null || vcard.Relations != null) { vcard = (VCard)vcard.Clone(); list[i] = vcard; if (vcard.Members != null) { List <RelationProperty?> members = vcard.Members.ToList(); vcard.Members = members; DoSetReferences(list, members); } if (vcard.Relations != null) { List <RelationProperty?> relations = vcard.Relations.ToList(); vcard.Relations = relations; DoSetReferences(list, relations); } } } return(list);