e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
170 lines
5.0 KiB
C#
170 lines
5.0 KiB
C#
//-----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace System.Activities
|
|
{
|
|
using System;
|
|
using System.Runtime.Serialization;
|
|
using System.Collections.Generic;
|
|
using System.Runtime;
|
|
using System.Collections.ObjectModel;
|
|
|
|
// used internally for performance in cases where a common usage pattern is a single item
|
|
[DataContract]
|
|
class HybridCollection<T>
|
|
where T : class
|
|
{
|
|
List<T> multipleItems;
|
|
T singleItem;
|
|
|
|
public HybridCollection()
|
|
{
|
|
}
|
|
|
|
public HybridCollection(T initialItem)
|
|
{
|
|
Fx.Assert(initialItem != null, "null is used as a sentinal value and is not a valid item value for a hybrid collection");
|
|
this.singleItem = initialItem;
|
|
}
|
|
|
|
public T this[int index]
|
|
{
|
|
get
|
|
{
|
|
if (this.singleItem != null)
|
|
{
|
|
Fx.Assert(index == 0, "Out of range with a single item");
|
|
return this.singleItem;
|
|
}
|
|
else if (this.multipleItems != null)
|
|
{
|
|
Fx.Assert(index >= 0 && index < this.multipleItems.Count, "Out of range with multiple items.");
|
|
|
|
return this.multipleItems[index];
|
|
}
|
|
|
|
Fx.Assert("Out of range. There were no items in the HybridCollection.");
|
|
return default(T);
|
|
}
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get
|
|
{
|
|
if (this.singleItem != null)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (this.multipleItems != null)
|
|
{
|
|
return this.multipleItems.Count;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
protected T SingleItem
|
|
{
|
|
get
|
|
{
|
|
return this.singleItem;
|
|
}
|
|
}
|
|
|
|
protected IList<T> MultipleItems
|
|
{
|
|
get
|
|
{
|
|
return this.multipleItems;
|
|
}
|
|
}
|
|
|
|
[DataMember(EmitDefaultValue = false, Name = "multipleItems")]
|
|
internal List<T> SerializedMultipleItems
|
|
{
|
|
get { return this.multipleItems; }
|
|
set { this.multipleItems = value; }
|
|
}
|
|
|
|
[DataMember(EmitDefaultValue = false, Name = "singleItem")]
|
|
internal T SerializedSingleItem
|
|
{
|
|
get { return this.singleItem; }
|
|
set { this.singleItem = value; }
|
|
}
|
|
|
|
public void Add(T item)
|
|
{
|
|
Fx.Assert(item != null, "null is used as a sentinal value and is not a valid item value for a hybrid collection");
|
|
if (this.multipleItems != null)
|
|
{
|
|
this.multipleItems.Add(item);
|
|
}
|
|
else if (this.singleItem != null)
|
|
{
|
|
this.multipleItems = new List<T>(2);
|
|
this.multipleItems.Add(this.singleItem);
|
|
this.multipleItems.Add(item);
|
|
this.singleItem = null;
|
|
}
|
|
else
|
|
{
|
|
this.singleItem = item;
|
|
}
|
|
}
|
|
|
|
public ReadOnlyCollection<T> AsReadOnly()
|
|
{
|
|
if (this.multipleItems != null)
|
|
{
|
|
return new ReadOnlyCollection<T>(this.multipleItems);
|
|
}
|
|
else if (this.singleItem != null)
|
|
{
|
|
return new ReadOnlyCollection<T>(new T[1] { this.singleItem });
|
|
}
|
|
else
|
|
{
|
|
return new ReadOnlyCollection<T>(new T[0]);
|
|
}
|
|
}
|
|
|
|
// generally used for serialization purposes
|
|
public void Compress()
|
|
{
|
|
if (this.multipleItems != null && this.multipleItems.Count == 1)
|
|
{
|
|
this.singleItem = this.multipleItems[0];
|
|
this.multipleItems = null;
|
|
}
|
|
}
|
|
|
|
public void Remove(T item)
|
|
{
|
|
Remove(item, false);
|
|
}
|
|
|
|
internal void Remove(T item, bool searchingFromEnd)
|
|
{
|
|
if (this.singleItem != null)
|
|
{
|
|
Fx.Assert(object.Equals(item, this.singleItem), "The given item should be in this list. Something is wrong in our housekeeping.");
|
|
this.singleItem = null;
|
|
}
|
|
else
|
|
{
|
|
Fx.Assert(this.multipleItems != null && this.multipleItems.Contains(item), "The given item should be in this list. Something is wrong in our housekeeping.");
|
|
int position = (searchingFromEnd) ? this.multipleItems.LastIndexOf(item) : this.multipleItems.IndexOf(item);
|
|
if (position != -1)
|
|
{
|
|
this.multipleItems.RemoveAt(position);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|