Skip to content

Instantly share code, notes, and snippets.

@weitzhandler
Created June 2, 2017 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weitzhandler/8483c718f4f6bda20e3a960e232f017b to your computer and use it in GitHub Desktop.
Save weitzhandler/8483c718f4f6bda20e3a960e232f017b to your computer and use it in GitHub Desktop.
ScalarCollection
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;
namespace System.Collections.Specialized
{
/// <summary>
/// If you add read/write properties, don't forget to attribute with NotMapped, unless you want it in the database.
/// </summary>
/// <typeparam name="T"></typeparam>
#if NET462
[ComplexType]
#endif
public abstract class ScalarCollectionBase<T> :
#if NET462
Collection<T>
#else
ObservableCollection<T>
#endif
{
public static readonly string DefaultSeparator = Environment.NewLine;
public virtual string Replacement { get; } = "\u23ce";
public virtual IEqualityComparer<T> Comparer { get; } = EqualityComparer<T>.Default;
protected ScalarCollectionBase(params T[] values)
: base(values.Where(v => v != null).Distinct().ToList() ?? new List<T>())
{ }
protected virtual string Separator { get; } = DefaultSeparator.ToString();
protected virtual bool AllowDuplicates { get; } = false;
/// <summary>
/// Gets or sets a linebreak-separated collection of the column content.
/// </summary>
#if NET462
[Browsable(false)]
#endif
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Not to be used directly by user, use Items property instead.")]
public string Data
{
get
{
var data = Items.Select(item => Serialize(item).Replace(Separator, Replacement));
return string.Join(Separator, data.Where(s => s?.Length > 0));
}
set
{
Items.Clear();
if (string.IsNullOrWhiteSpace(value))
return;
foreach (var item in value.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries).Select(item => Deserialize(item)))
Items.Add(item);
}
}
public void AddRange(params T[] items)
{
if (items != null)
foreach (var item in items)
Add(item);
}
protected abstract string Serialize(T item);
protected abstract T Deserialize(string item);
protected override void SetItem(int index, T item)
{
if (AllowDuplicates || !Items.Contains(item, Comparer))
base.SetItem(index, item);
}
protected override void InsertItem(int index, T item)
{
if (AllowDuplicates || !Items.Contains(item, Comparer))
base.InsertItem(index, item);
}
}
public class ScalarStringCollection : ScalarCollectionBase<string>
{
public ScalarStringCollection() : this(null) { }
public ScalarStringCollection(params string[] values) : base(values)
{
}
protected virtual bool IsCaseInsensitive { get; } = false;
public override IEqualityComparer<string> Comparer => IsCaseInsensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
protected override string Serialize(string item) => item;
protected override string Deserialize(string item) => item;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment