gpt4 book ai didi

c# - 为 MemoryCache(或任何缓存)实现通用 Get

转载 作者:太空狗 更新时间:2023-10-29 17:55:58 25 4
gpt4 key购买 nike

我正在尝试编写一个“简单” 通用 Get<T> ;扩展为 System.Runtime.MemoryCache .

为什么“简单”?因为通常我在缓存对象之前就知道对象的真实类型,所以当我从缓存中检索它时,我不会以不可预测的方式转换它。

例如:如果 boolean "true"值以 cacheKey "id"存储在缓存中,那么

Get<string>("id") == "true";
Get<int>("id") == 1; // any result > 0 is okay
Get<SomeUnpredictableType> == null; // just ignore these trouble conversions

这是我不完整的实现:

public static T DoGet<T>(this MemoryCache cache, string key) {
object value = cache.Get(key);
if (value == null) {
return default(T);
}
if (value is T) {
return (T)value;
}

// TODO: (I'm not sure if following logic is okay or not)
// 1. if T and value are both numeric type (e.g. long => double), how to code it?
// 2. if T is string, call something like Convert.ToString()

Type t = typeof(T);
t = (Nullable.GetUnderlyingType(t) ?? t);
if (typeof(IConvertible).IsAssignableFrom(value.GetType())) {
return (T)Convert.ChangeType(value, t);
}
return default(T);
}

非常感谢任何建议。

===================================

更新(2016 年 4 月 11 日):

对于给出的那些好的建议,我实现了我的第一个版本的 Get

public class MemCache {
private class LazyObject<T> : Lazy<T> {
public LazyObject(Func<T> valueFactory) : base(valueFactory) { }
public LazyObject(Func<T> valueFactory, LazyThreadSafetyMode mode) : base(valueFactory, mode) { }
}

private static T CastValue<T>(object value) {
if (value == null || value is DBNull) {
return default(T);
}
Type valType = value.GetType();
if (valType.IsGenericType && valType.GetGenericTypeDefinition() == typeof(LazyObject<>)) {
return CastValue<T>(valType.GetProperty("Value").GetValue(value));
}
if (value is T) {
return (T)value;
}
Type t = typeof(T);
t = (Nullable.GetUnderlyingType(t) ?? t);
if (typeof(IConvertible).IsAssignableFrom(t) && typeof(IConvertible).IsAssignableFrom(value.GetType())) {
return (T)Convert.ChangeType(value, t);
}
return default(T);
}

private MemoryCache m_cache;

public T Get<T>(string key) {
return CastValue<T>(m_cache.Get(key));
}

public void Set<T>(string key, T value, CacheDependency dependency) {
m_cache.Set(key, value, dependency.AsCacheItemPolicy());
}

public T GetOrAdd<T>(string key, Func<T> fnValueFactory, CacheDependency dependency) {
LazyObject<T> noo = new LazyObject<T>(fnValueFactory, LazyThreadSafetyMode.ExecutionAndPublication);
LazyObject<T> old = m_cache.AddOrGetExisting(key, noo, dependency.AsCacheItemPolicy()) as LazyObject<T>;
try {
return CastValue<T>((old ?? noo).Value);
} catch {
m_cache.Remove(key);
throw;
}
}

/* Remove/Trim ... */
}

最佳答案

基本工作是编写 CastValue 以将任何对象转换为所需类型。而且它不必处理非常复杂的情况,因为缓存中的对象类型对于程序员来说是可预测的。这是我的版本。

public static T CastValue<T>(object value) {
if (value == null || value is DBNull) {
return default(T);
}
if (value is T) {
return (T)value;
}
Type t = typeof(T);
t = (Nullable.GetUnderlyingType(t) ?? t);
if (typeof(IConvertible).IsAssignableFrom(t) && typeof(IConvertible).IsAssignableFrom(value.GetType())) {
return (T)Convert.ChangeType(value, t);
}
return default(T);
}

关于c# - 为 MemoryCache(或任何缓存)实现通用 Get<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36466490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com