ObservableCollection에이 컬렉션에서 상속을 위치 기반 색인 생성.
문자열 기반 인덱싱의 경우 ObservableDictionary의 사람들 구현을 조사 할 수 있습니다.
개인적으로 성능 향상을 위해 ObservableCollection에서 파생 된 HashedObservableCollection을 작성했습니다.이 목록에는 조회 시간 단축을 위해 색인 할 키 사전이 포함되어 있습니다. InsertItem, RemoveItem 및 ClearItems를 재정 의하여 사전을 동기화 상태로 유지합니다.
예를 들어, 키는 모든 유형이 될 수 있지만 키가 변경되지 않는다고 가정합니다. 항목이 바뀌면 동일한 키를 가진 객체로 바뀝니다. 이 작업을 단순화하려면 TKey를 String으로 바꿀 수 있습니다.
코드 :
여기
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace foson.Utils
{
/// <summary>
/// Represents BindableCollection indexed by a dictionary to improve lookup/replace performance.
/// </summary>
/// <remarks>
/// Assumes that the key will not change and is unique for each element in the collection.
/// Collection is not thread-safe, so calls should be made single-threaded.
/// </remarks>
/// <typeparam name="TValue">The type of elements contained in the BindableCollection</typeparam>
/// <typeparam name="TKey">The type of the indexing key</typeparam>
public class HashedBindableCollection<TValue, TKey> : ObservableCollection<TValue>
{
protected internal Dictionary<TKey, int> indecies = new Dictionary<TKey, int>();
protected internal Func<TValue, TKey> _keySelector;
/// <summary>
/// Create new HashedBindableCollection
/// </summary>
/// <param name="keySelector">Selector function to create key from value</param>
public HashedBindableCollection(Func<TValue, TKey> keySelector)
: base()
{
if (keySelector == null) throw new ArgumentException("keySelector");
_keySelector = keySelector;
}
#region Protected Methods
protected override void InsertItem(int index, TValue item)
{
var key = _keySelector(item);
if (indecies.ContainsKey(key))
throw new DuplicateKeyException(key.ToString());
if (index != this.Count)
{
foreach (var k in indecies.Keys.Where(k => indecies[k] >= index).ToList())
{
indecies[k]++;
}
}
base.InsertItem(index, item);
indecies[key] = index;
}
protected override void ClearItems()
{
base.ClearItems();
indecies.Clear();
}
protected override void RemoveItem(int index)
{
var item = this[index];
var key = _keySelector(item);
base.RemoveItem(index);
indecies.Remove(key);
foreach (var k in indecies.Keys.Where(k => indecies[k] > index).ToList())
{
indecies[k]--;
}
}
#endregion
public virtual bool ContainsKey(TKey key)
{
return indecies.ContainsKey(key);
}
/// <summary>
/// Gets or sets the element with the specified key. If setting a new value, new value must have same key.
/// </summary>
/// <param name="key">Key of element to replace</param>
/// <returns></returns>
public virtual TValue this[TKey key]
{
get { return this[indecies[key]]; }
set
{
//confirm key matches
if (!_keySelector(value).Equals(key))
throw new InvalidOperationException("Key of new value does not match");
if (!indecies.ContainsKey(key))
{
this.Add(value);
}
else
{
this[indecies[key]] = value;
}
}
}
/// <summary>
/// Replaces element at given key with new value. New value must have same key.
/// </summary>
/// <param name="key">Key of element to replace</param>
/// <param name="value">New value</param>
///
/// <exception cref="InvalidOperationException"></exception>
/// <returns>False if key not found</returns>
public virtual bool Replace(TKey key, TValue value)
{
if (!indecies.ContainsKey(key)) return false;
//confirm key matches
if (!_keySelector(value).Equals(key))
throw new InvalidOperationException("Key of new value does not match");
this[indecies[key]] = value;
return true;
}
public virtual bool Remove(TKey key)
{
if (!indecies.ContainsKey(key)) return false;
this.RemoveAt(indecies[key]);
return true;
}
}
public class DuplicateKeyException : Exception
{
public string Key { get; private set; }
public DuplicateKeyException(string key)
: base("Attempted to insert duplicate key " + key + " in collection")
{
Key = key;
}
}
}
자세한 내용이 필요합니다.ordinal 및 string 인덱스가있는 ObservableCollection의 C# 구문입니다. – Paparazzi
'public 가상 TValue this [TKey key]'메소드를 살펴보십시오. 각 오버로드가 다른 매개 변수 유형을 가지고있는 한 인덱서 함수 ('public XXX this [YYY]')를 여러 번 오버로드 할 수 있습니다. – foson
굉장! 그 생성자를 정말로 좋아합니다. ObservableCollection에서 상속 받음으로써 서수 부분을 처리합니다. – Paparazzi