У меня есть класс, который я использую для проверки аргументов метода, который вы вызываете в форме:
public void SomeMethod(string anArg)
{
Ensure.ArgumentNotNull(() => anArg);
}
Если аргумент равен нулю, выдается ArgumentNullException
с именем свойства. Это делается так:
public static void ArgumentNotNull<T>(Expression<Func<T>> expression) where T : class
{
var value = expression.Compile()();
if (value == null)
{
throw new ArgumentNullException(expression.GetMemberName());
}
}
Где GetMemberName
- это метод расширения, который я написал.
Проблема, с которой я столкнулся, заключается в том, что вызов Compile выполняется очень медленно, поэтому я хотел бы кэшировать результат, но я не могу найти ключ кеша, который будет достаточно уникальным чтобы предотвратить конфликты кеша, но не настолько уникальные, чтобы кеш стал недействительным.
Мое лучшее усилие на данный момент:
internal static class ExpressionCache<T>
{
private static readonly Dictionary<string, Func<T>> Cache = new Dictionary<string, Func<T>>();
public static Func<T> CachedCompile(Expression<Func<T>> targetSelector)
{
Func<T> cachedFunc;
var cacheKey = targetSelector + targetSelector.Body.ToString();
if (!Cache.TryGetValue(cacheKey, out cachedFunc))
{
cachedFunc = targetSelector.Compile();
Cache[cacheKey] = cachedFunc;
}
return cachedFunc;
}
}
Но это все еще вызывает конфликты ключей кэша. Что может быть лучше?