鉴于您最近的评论,该值是一个可变长度的字符串,计算字典中每个项目的大小应该很容易。我会考虑通过创建自己的缓存对象(可能只是包装字典)并在将项目添加到缓存中和从缓存中删除时跟踪总大小来节省时间和精力。这样,您可以随时通过查看您一直跟踪的值来了解缓存中值的总大小。
如果您需要缓存来公开完整的IDictionary 功能,您可以实现接口,将其委托给“真实”字典并修改Add 和Remove 操作中的累积大小值。如果您不需要缓存来公开完整的IDictionary 功能,只需定义一个精简的接口(可能只有Add、Contains 和Remove 方法和CumulativeSize 属性。或者,您可能决定实现一个没有接口的缓存对象。如果是我,我会使用IDictionary 或定义一个接口,如ICache。
因此,您的缓存可能看起来像这样(未编译且未经测试):
public interface ICacheWithCumulativeSize
{
void Add(string key, string value);
bool Contains(string key);
void Remove(string key);
int CumulativeSize { get; }
}
public class MyCache : ICacheWithCumulativeSize
{
private IDictionary<string, string> dict = new Dictionary<string, string>();
public void Add(string key, string value)
{
CumulativeSize += value.Length;
dict[key] = value;
}
public bool Contains(string key)
{
return dict.ContainsKey(key);
}
public void Remove(string key)
{
string toRemove = dict[key];
CumulativeSize -= value.Length;
dict.Remove(key);
}
int CumulativeSize { public get; private set; }
}
这很粗糙。显然,它可以更高效、更健壮。我没有对Add 和Remove 进行任何检查以查看密钥是否已经存在等,但我认为您可能明白了。此外,作为值存储在字典中的字符串可能会在外部进行修改(可能不在您的程序中,但在理论上),因此当值是从 CumulativeSize 中减去字符串时的长度从缓存中删除的字符串可能与最初添加该字符串时的长度不同。如果这是一个问题,您可以考虑将值的副本存储在内部字典中。我对您的申请了解得不够多,无法判断这是否是个好主意。
为了完整性...这是一个粗略的实现,它简单地包装了一个字典,公开了 IDictionary 接口,并跟踪缓存中项目的总大小。它有更多的防御性代码,主要是为了保护大小累加器。我可能认为棘手的唯一部分是索引设置器...我的实现检查正在设置的索引是否已经存在。如果是这样,累积值会适当递减,然后根据输入值的大小递增。否则,我认为这很简单。
public class MySpecialDictionary : IDictionary<string, string>
{
private IDictionary<string, string> dict = new Dictionary<string, string>();
public int TotalSize { get; private set; }
#region IDictionary<string,string> Members
public void Add(string key, string value)
{
dict.Add(key, value);
TotalSize += string.IsNullOrEmpty(value) ? 0 : value.Length;
}
public bool ContainsKey(string key)
{
return dict.ContainsKey(key);
}
public ICollection<string> Keys
{
get { return dict.Keys; }
}
public bool Remove(string key)
{
string value;
if (dict.TryGetValue(key, out value))
{
TotalSize -= string.IsNullOrEmpty(value) ? 0 : value.Length;
}
return dict.Remove(key);
}
public bool TryGetValue(string key, out string value)
{
return dict.TryGetValue(key, out value);
}
public ICollection<string> Values
{
get { return dict.Values; }
}
public string this[string key]
{
get
{
return dict[key];
}
set
{
string v;
if (dict.TryGetValue(key, out v))
{
TotalSize -= string.IsNullOrEmpty(v) ? 0 : v.Length;
}
dict[key] = value;
TotalSize += string.IsNullOrEmpty(value) ? 0 : value.Length;
}
}
#endregion
#region ICollection<KeyValuePair<string,string>> Members
public void Add(KeyValuePair<string, string> item)
{
dict.Add(item);
TotalSize += string.IsNullOrEmpty(item.Value) ? 0 : item.Value.Length;
}
public void Clear()
{
dict.Clear();
TotalSize = 0;
}
public bool Contains(KeyValuePair<string, string> item)
{
return dict.Contains(item);
}
public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
{
dict.CopyTo(array, arrayIndex);
}
public int Count
{
get { return dict.Count; }
}
public bool IsReadOnly
{
get { return dict.IsReadOnly; }
}
public bool Remove(KeyValuePair<string, string> item)
{
string v;
if (dict.TryGetValue(item.Key, out v))
{
TotalSize -= string.IsNullOrEmpty(v) ? 0 : v.Length;
}
return dict.Remove(item);
}
#endregion
#region IEnumerable<KeyValuePair<string,string>> Members
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
return dict.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return dict.GetEnumerator();
}
#endregion
}
祝你好运!