Is there anyway to cache function/method in C# - c#

I got bored with writing same to code again and again to cache the objects in data access layer.
Is there anyway to cache c# function results without much changes to functions.
Is there any framework supports this functionality at the moment?
Can i archive the same by writing custom "c# function attributes"? if so, drop me some points to start implementation?

Possibility 1: Use IL Weaving
Postsharp was mentioned before.
You could also try the MethodCache.Fody package.
Possibility 2: Use an Proxy / Interception Framework
Example (Ninject & Ninject.Interception):
public class CacheAttribute : InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Context.Kernel.Get<CachingInterceptor>();
}
}
public class CachingInterceptor : IInterceptor
{
private ICache Cache { get; set; }
public CachingInterceptor(ICache cache)
{
Cache = cache;
}
public void Intercept(IInvocation invocation)
{
string className = invocation.Request.Target.GetType().FullName;
string methodName = invocation.Request.Method.Name;
object[] arguments = invocation.Request.Arguments;
StringBuilder builder = new StringBuilder(100);
builder.Append(className);
builder.Append(".");
builder.Append(methodName);
arguments.ToList().ForEach(x =>
{
builder.Append("_");
builder.Append(x);
});
string cacheKey = builder.ToString();
object retrieve = Cache.Retrieve<object>(cacheKey);
if (retrieve == null)
{
invocation.Proceed();
retrieve = invocation.ReturnValue;
Cache.Store(cacheKey, retrieve);
}
else
{
invocation.ReturnValue = retrieve;
}
}
}
Then you could decorate functions like this:
[Cache]
public virtual Customer GetCustomerByID(int customerID)
{
return CustomerRepository.GetCustomerByID(customerID);
}
Intercepted functions have to be virtual and classes must be created by the Ninject kernel. If you rely on performance, you could proxy classes directly via Castle.DynamicProxy (which is internally used by Ninject.Extensions.Interception.DynamicProxy).
Possibility 3: Use an Expression wrapper
You could pass the function as expression, generate a caching key containing class, method and parameter information and invoke the expression if not found in your Cache. This adds more runtime overhead than AOP / Proxy frameworks, but will be sufficient for simple solutions.
private T CacheAction<T>(Expression<Func<T>> action, [CallerMemberName] string memberName = "") where T : class
{
MethodCallExpression body = (MethodCallExpression)action.Body;
ICollection<object> parameters = new List<object>();
foreach (MemberExpression expression in body.Arguments)
{
parameters.Add(((FieldInfo)expression.Member).GetValue(((ConstantExpression)expression.Expression).Value));
}
StringBuilder builder = new StringBuilder(100);
builder.Append(GetType().FullName);
builder.Append(".");
builder.Append(memberName);
parameters.ToList().ForEach(x =>
{
builder.Append("_");
builder.Append(x);
});
string cacheKey = builder.ToString();
T retrieve = Cache.Retrieve<T>(cacheKey);
if (retrieve == null)
{
retrieve = action.Compile().Invoke();
Cache.Store(cacheKey, retrieve);
}
return retrieve;
}
public Customer GetCustomerByID(int customerID)
{
return CacheAction(() => CustomerRepository.GetCustomerByID(customerID));
}

You can create caching attributes with PostSharp. You can use the Cache attribute.

If I read you question correct, the right term for what you want is memoization. Wikipedia gives more details on this subjects. Unfortunately there is no reference to a C# library supporting it.

Lazy store it's value after first run.
Example: http://msdn.microsoft.com/en-us/vstudio/bb870976

I use this simple implementation of the System.Runetime.Caching namespace:
public class InMemoryCache : ICacheService
{
public T GetOrSet<T>(string cacheKey, Func<T> getItemCallback) where T : class
{
T item = MemoryCache.Default.Get(cacheKey) as T;
if (item == null)
{
item = getItemCallback();
MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddHours(4));
}
return item;
}
public void Clear(string cacheKey)
{
MemoryCache.Default.Remove(cacheKey);
}
}
interface ICacheService
{
T GetOrSet<T>(string cacheKey, Func<T> getItemCallback) where T : class;
void Clear(string cacheKey);
}
Can be used in the following manner:
var cacheProvider = new InMemoryCache();
var cachedResult = cacheProvider.GetOrSet("YourCacheKey",
() => MethodToCache());
First call to the method will cache the result, the next call will return the cached result.

The Cache Application block is Microsoft's answer to built in library for Caching in .NET.

I suggest Spring.Net AOP.
It basically creates a proxy and the calls can be redirected from/to the cache.
http://www.springframework.net/doc/reference/html/aop-quickstart.html
and then you can have something like that for your advice:
public class CachingAroundAdvice : IMethodInterceptor
{
#region Variable Declarations
private Priority priority = Priority.Normal;
#endregion
public object Invoke(IMethodInvocation invocation)
{
// declare local variables
string cacheKey = string.Empty;
object dataObject = null;
// build cache key with some algorithm
cacheKey = CreateCacheKey(invocation.Method, invocation.Arguments);
// retrieve item from cache
dataObject = CacheManager.Cache.GetData(cacheKey);
// if the dataobject is not in cache proceed to retrieve it
if (null == dataObject)
{
dataObject = invocation.Proceed();
// add item to cache
CacheManager.Cache.Add(cacheKey, dataObject, CachePriority, null, Expiration);
}
// return data object
return dataObject;
}

You could use a Dictionary to cache the function. A dictionary maps keys to values and a function maps arguments to values. So conceptually, a dictionary fits as a cache for a function. Here's a simple class to do that:
/// <summary>
/// The lazy function map caches the results of calls to the backing function. Every time the function is called on an argument u and returns v,
/// the pair (u, v) is stored in the dictionary.
/// </summary>
class LazyFunctionMapImpl<T, U> : ILazyFunctionMap<T, U>
{
private readonly Dictionary<T, U> _backingDictionary;
private readonly Func<T, U> _backingFunction;
public LazyFunctionMapImpl(Func<T, U> backingFunction)
{
_backingDictionary = new Dictionary<T, U>();
_backingFunction = backingFunction;
}
public U this[T index]
{
get
{
if (_backingDictionary.ContainsKey(index))
{
return _backingDictionary[index];
}
U valueAtIndex = _backingFunction(index);
_backingDictionary.Add(index, valueAtIndex);
return valueAtIndex;
}
}
public void Clear()
{
_backingDictionary.Clear();
}
}
And here's a couple of interfaces to go with it:
/// <summary>
/// A function map that should lazily cache param/result pairs until clear is called.
/// </summary>
public interface ILazyFunctionMap<T, U> : IFunctionMap<T, U>
{
/// <summary>
/// Should invalidate any caches forcing the underyling function to be called afresh
/// </summary>
void Clear();
}
public interface IFunctionMap<T, U>
{
/// <summary>
/// Mapped values representing the underlying function.
/// </summary>
U this[T index] { get; }
}

Related

C# Generic Interface and Factory Pattern

I am trying to create a Generic interface where the parameter type of one of the methods is defined by the generic
EDIT
I've changed the question slightly after realising I have probably confused matters by specifying a type parameter in the Factory creation method. What I have is two types of API calls that I need to make to a 3rd party API. The first retrieves a record from the API using an Id that is an int. The second also retrieves a record from the API but the Id is a string (guid). I have a class for each record type (ClientEntity and InvoiceEntity) that both implement a Generic Interface where I pass in the Id type
This is the Interface in which I declare a Method with an id Parameter
public interface IGeneric<TId>
{
void ProcessEntity(TId id);
}
I implement the interface in a couple of classes, one sets the id to be an int, the other a string.
public class ClientEntity: IGeneric<int> // Record with Id that is an int
{
public void ProcessEntity(int id)
{
Console.WriteLine(id);
// call 3rd party API with int Id
}
}
public class InvoiceEntity: IGeneric<string> // Record with Id that is a string (guid)
{
public void ProcessEntity(string id)
{
Console.WriteLine(id);
// call 3rd party API with string Id
}
}
What I would like to know is how do I use this within a factory pattern?
public static class GenericFactory
{
public static IGeneric<WhatGoesHere> CreateGeneric(string recordType)
{
if (recordType == "Client")
{
return new ClientEntity();
}
if (type == "Invoice")
{
return new InvoiceEntity();
}
return null;
}
}
The objective is to use the factory to instantiate the correct class so that I can call the ProcessEntity method
EDIT
I don't want to have to pass in the Generic type to the factory method because the class that is created by the factory should handle that. When I create the object, I don't know what Id type is required, I want the factory to handle that
e.g.
var myGeneric = GenericFactory.CreateGeneric("Client");
myGeneric.ProcessEntity("guid")
or
var myGeneric = GenericFactory.CreateGeneric("Invoice");
myGeneric.ProcessEntity(1234)
I hope that makes sense
You should be able to do something like this:
public static class GenericFactory
{
public static IGeneric<T> CreateGeneric<T>()
{
if (typeof(T) == typeof(string))
{
return (IGeneric<T>) new GenericString();
}
if (typeof(T) == typeof(int))
{
return (IGeneric<T>) new GenericInt();
}
throw new InvalidOperationException();
}
}
You would use it like this:
var a = GenericFactory.CreateGeneric<string>();
var b = GenericFactory.CreateGeneric<int>();
Note that this uses a strongly-typed call rather than passing in the type name as a string (which may or may not be what you actually want).
If instead you want to pass a string for the type name, you will have to return an object because there is no way to return the actual type:
public static object CreateGeneric(string type)
{
switch (type)
{
case "string": return new GenericString();
case "int": return new GenericInt();
default: throw new InvalidOperationException("Invalid type specified.");
}
}
Obviously if you have an object you would normally have to cast it to the right type in order to use it (which requires that you know the actual type).
Alternatively, you could use reflection to determine what methods it contains, and call them that way. But then you'd still need to know the type in order to pass a parameter of the right type.
I think that what you are attempting to do here is not the right approach, which you will discover once you start trying to use it.
Hacky solution: Use dynamic
Nevertheless, there is one way you can get something close to what you want: Use dynamic as follows (assuming that you are using the object CreateGeneric(string type) factory method from above):
dynamic a = GenericFactory.CreateGeneric("string");
dynamic b = GenericFactory.CreateGeneric("int");
a.ProcessEntity("A string");
b.ProcessEntity(12345);
Be aware that dynamic uses reflection and code generation behind the scenes, which can make the initial calls relatively slow.
Also be aware that if you pass the wrong type to a method accessed via dynamic, you'll get a nasty runtime exception:
dynamic a = GenericFactory.CreateGeneric("string");
a.ProcessEntity(12345); // Wrong parameter type!
If you run that code, you get this kind of runtime exception:
Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The best overloaded method match for 'ConsoleApplication1.GenericString.ProcessEntity(string)' has some invalid arguments
at CallSite.Target(Closure , CallSite , Object , Int32 )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
at ConsoleApplication1.Program.Main() in D:\Test\CS6\ConsoleApplication1\Program.cs:line 71
Usually for that Factory using some DI container (DI can be useful, for example, when GenericInt or GenericString has dependencies), but to demonstrate just Idea how you can resolve this:
void Main()
{
GenericFactory.CreateGeneric<int>();
GenericFactory.CreateGeneric<string>();
}
public static class GenericFactory
{
private static Dictionary<Type, Type> registeredTypes = new Dictionary<System.Type, System.Type>();
static GenericFactory()
{
registeredTypes.Add(typeof(int), typeof(GenericInt));
registeredTypes.Add(typeof(string), typeof(GenericString));
}
public static IGeneric<T> CreateGeneric<T>()
{
var t = typeof(T);
if (registeredTypes.ContainsKey(t) == false) throw new NotSupportedException();
var typeToCreate = registeredTypes[t];
return Activator.CreateInstance(typeToCreate, true) as IGeneric<T>;
}
}
public interface IGeneric<TId>
{
TId Id { get; set; }
void ProcessEntity(TId id);
}
public class GenericInt : IGeneric<int>
{
public int Id { get; set; }
public void ProcessEntity(int id)
{
Console.WriteLine(id);
}
}
public class GenericString : IGeneric<string>
{
public string Id { get; set; }
public void ProcessEntity(string id)
{
Console.WriteLine(id);
}
}
The answer marked correct is fine if you want to use Static class but but what if you
want to return an DI injected type instead of newing an object? I suggest the
following!
public interface IGenericFactory
{
IGeneric<T> GetGeneric<T>() where T : class;
}
public class GenericFactory: IGenericFactory
{
private readonly IGeneric<int> intGeneric;
private readonly IGeneric<string> stringGeneric;
public GenericFactory(IGeneric<int> intG, IGeneric<string> stringG)
{
intGeneric = intG;
stringG = stringG;
}
public IGeneric<T> GetGeneric<T>() where T : class
{
if (typeof(T) == typeof(IGeneric<int>))
return (IGeneric<T>)Convert.ChangeType(intGeneric, typeof(IGeneric<T>));
if (typeof(T) == typeof(IGeneric<string>))
return (IGeneric<T>)Convert.ChangeType(stringGeneric,typeof(IGeneric<T>));
else
throw new NotSupportedException();
}
}
Please note i simply injected the two expected return types for clarity in the constructor. I could have implemented the factory as a Dictionary and injected the return objects into this Dictionary. Hope it helps.
I'm thinking you don't want to have to enter the type parameter similar to the LINQ methods. However the magic behind that happens because the type parameter is used in the normal parameter definitions. For example in the ToList<string>() method you can see that TSource is used between the parenthesis.
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source);
That's how the compiler knows that you want a List<string> if you call ToList() instead of ToList<string>() when called from an IEnumerable<string>
However, I don't think you need a generic type parameter in your factory method at all. All you have to do is create a non-generic version of your TGeneric<TId>
public interface IGeneric { }
public interface IGeneric<TId> : IGeneric
{
void ProcessEntity(TId id);
}
And remove the <WhatGoesHere> from the CreateGeneric method:
public static IGeneric CreateGeneric(string recordType)
{
if (recordType == "Client")
{
return new ClientEntity();
}
if (recordType == "Invoice")
{
return new InvoiceEntity();
}
return null;
}
If the function does not know the type, make it generic.
If the children are generics of different types (<int>, <string>), return object and cast inside the same factory class (Factory<T>), It is safe by typeof.
Personally, I prefer to specify the type with generics, without using an additional parameter, eg a string.
public class Program
{
public static void Main(string[] args)
{
List<Number> something = new();
Do(something);
}
public static void Do<T>(List<T> list)
{
list.Add(Factory<T>.Create());
}
}
public abstract class Factory<T>
{
private static Object ConcreteF()
{
if (typeof(T) == typeof(Number))
return new ChildGenericNumber();
throw new Exception("");
}
public static T Create()
{
return (Factory<T>)ConcreteF()).Build();
}
protected abstract T Build();
}

What is the best approach for caching database queries

I'm writing a management intelligence application which requires quite a lot of complex database querying with some queries being quite expensive. To aid performance I'm using Memcached quite heavily to store as much as I can in memory.
This has led to quite a lot of duplication in my code which I'm eager to get rid of and build a cleaner data access solution. Quite a lot of my data access functions have ended up looking like this..
public int NumberOfTimeouts(DateTime date, int? applicationId)
{
var functionCacheKey = "NumberOfTimeouts";
var cacheKey = string.Format("{0}-{1}-{2}-{3}", RepositoryCacheKey, functionCacheKey, date, applicationId);
var cachedNumberTimeouts = _cache.Retrieve(cacheKey);
if (cachedNumberTimeouts != null)
{
return (int)cachedNumberTimeouts;
}
//query logic here, calculates numberOfTimeouts
UpdateCache(date, cacheKey, numberOfTimeouts);
return numberOfTimeouts;
}
I'm just not too sure what the standard approach is to this, could it involve using a custom attribute class or something similar?
This is a cross-cutting concern. The Decorator pattern may be applicable here. I may be inexperienced in this pattern, however I will give it a shot
// model
public class CustomObject
{
public int Id { get; set; }
}
// interface
public interface IRepository<T>
{
IEnumerable<T> Find(Expression<Func<T, bool>> expression);
}
public interface ICacheableRepository<T>
{
IEnumerable<T> Find(Expression<Func<T, bool>> expression, Func<int> cacheKey);
}
public interface IRepositoryCacheManager<T>
{
IEnumerable<T> Get(int key);
bool Any(int key);
void Add(int key, IEnumerable<T> result);
}
// cache manager
public class RepositoryCacheManager<T> : IRepositoryCacheManager<T>
{
private Dictionary<int, IEnumerable<T>> cache = new Dictionary<int,IEnumerable<T>>();
#region IRepositoryCache<T> Members
public IEnumerable<T> Get(int key)
{
return cache[key];
}
public bool Any(int key)
{
IEnumerable<T> result = null;
return cache.TryGetValue(key, out result);
}
public void Add(int key, IEnumerable<T> result)
{
cache.Add(key, result);
}
#endregion
}
// cache repository decorator
public class CachedRepositoryDecorator<T> : IRepository<T>, ICacheableRepository<T>
{
public CachedRepositoryDecorator(IRepositoryCacheManager<T> cache
, IRepository<T> member)
{
this.member = member;
this.cache = cache;
}
private IRepository<T> member;
private IRepositoryCacheManager<T> cache;
#region IRepository<T> Members
// this is not caching
public IEnumerable<T> Find(Expression<Func<T, bool>> expression)
{
return member.Find(expression);
}
#endregion
#region ICacheableRepository<T> Members
public IEnumerable<T> Find(Expression<Func<T, bool>> expression, Func<int> cacheKey)
{
if (cache.Any(cacheKey()))
{
return cache.Get(cacheKey());
}
else
{
IEnumerable<T> result = member.Find(expression);
cache.Add(cacheKey(), result);
return result;
}
}
#endregion
}
// object repository
public class CustomObjectRepository : IRepository<CustomObject>
{
#region IRepository<CustomObject> Members
public IEnumerable<CustomObject> Find(Expression<Func<CustomObject, bool>> expression)
{
List<CustomObject> cust = new List<CustomObject>();
// retrieve data here
return cust;
}
#endregion
}
// example
public class Consumer
{
// this cache manager should be persistent, maybe can be used in static, etc
IRepositoryCacheManager<CustomObject> cache = new RepositoryCacheManager<CustomObject>();
public Consumer()
{
int id = 25;
ICacheableRepository<CustomObject> customObjectRepository =
new CachedRepositoryDecorator<CustomObject>(
cache
, new CustomObjectRepository()
);
customObjectRepository.Find(k => k.Id == id, () => { return id; });
}
}
Please note:
I haven't tested this code, don't know whether it is fully functional or not. I just describe the illustration
Yes, this has code smell by having the ICacheableRepository overloading for Find, however I am incapable in using Expression as Key in Dictionary
The pros:
This CachedRepositoryDecorator can be used to ANY generic repository (reusable)
No caching logic inside the select process, emphasize SRP
The cons:
Hard to implement without ORM, maybe you will need some tweaks with reflection to make it works without ORM
Hard to understand at beginning
Hard to wire without DI Container
Credit to this article :)
I think the Unit of Work pattern is what you need.
More info:
http://martinfowler.com/eaaCatalog/unitOfWork.html
http://www.codeproject.com/Articles/581487/Unit-of-Work-Design-Pattern
http://msdn.microsoft.com/en-us/magazine/dd882510.aspx
Or a framework that contains the UoW pattern: https://github.com/riteshrao/ncommon

Creating a generic class pool where you give the generic parameter and get a generic object that used that parameter

Goal
I have a generic class GenericClass<T> and I want to pool instances.
I'm interested in seeing if I can get the syntax:
MyGenericPool = new GenericPool<GenericClass>();
// Or maybe it's MyGenericPool = new GenericPool<GenericClass<>>();
GenericClass<TGenericParam> GenericClassInstance =
MyGenericPool.Get<TGenericParam>();
(My understanding of generics says, no I can't, don't be silly the syntax doesn't exist / wouldn't work, but I'm intested in what others think).
Showing my workings
I'm a bit doubtful as from my understanding the types GenericClass<string> and GenericClass<int> aren't really related from the type system's point of view.
Now, I realise that I can get close, i.e.:
GenericClass<TGenericParam> GenericClassInstance =
GenericPool.Get<GenericClass<TGenericParam>>();
and then have the GenericPool just store a Dictionary<Type, ObjectPool<object>> somewhere.
I'm interested in seeing if I can avoid having to do that. I don't want to have to specify the generic type every time when, as the caller, i'm only changing the generic type parameter. I'd also like to be able to enforce (compile time) that all objects going into my GenericObjectPool<T> are of a set generic type (T<>).
I think the problem stems from not being able to treat a generic type parameter as being generic its self. If I could do that (can I already??) then maybe something like the below might work:
public class GenericClassPool<TGeneric> where TGeneric : class<>
{
private readonly Dictionary<Type, object> objectPools = new Dictionary<Type, object>();
private void EnsureObjectPoolExists<TGenericParam>()
{
if (!objectPools.ContainsKey(typeof(TGenericParam)))
{
objectPools.Add(typeof(TGenericParam), new ObjectPool<TGeneric<TGenericParam>>(() => Activator.CreateInstance(typeof(TGeneric<TGenericParam>)) as TGeneric<TGenericParam>));
}
}
private ObjectPool<TGeneric<TGenericParam>> GetPool<TGenericParam>()
{
EnsureObjectPoolExists<TGenericParam>();
return (objectPools[typeof(TGenericParam)] as ObjectPool<TGeneric<TGenericParam>>);
}
public void Add<TTypeParam>(TGeneric<TGenericParam> obj)
{
EnsureObjectPoolExists<TTypeParam>();
GetPool<TGenericParam>().Add(obj);
}
public TGeneric<TGenericParam> Get<TGenericParam>()
{
return GetPool<TGenericParam>().Get() as TGeneric<TGenericParam>;
}
}
Question
Can I get the syntax I want (at the top)? If not, how close can I get?
The solution / syntax you are trying to achieve doesn't work that way, because you can't use a generic type without its type parameters as the type parameter to another generic type.
However, you could achieve similar results with the following approach:
Create a base class for the class pool that requires you to supply the complete generic type
Create a derived class for the specific generic type
Something like that:
public class ObjectPool
{
Dictionary<Type, object> _objectPool = new Dictionary<Type, object>();
public void Add<TKey, TValue>(TValue value)
{
_objectPool.Add(typeof(TKey), value);
}
public TValue Get<TKey, TValue>() where TValue : class
{
object value;
if(_objectPool.TryGetValue(typeof(TKey), out value))
return value as TValue;
return null;
}
}
public class GenericClassPool : ObjectPool
{
public void Add<TGenericParam>(GenericClass<TGenericParam> obj)
{
Add<TGenericParam, GenericClass<TGenericParam>>(obj);
}
public GenericClass<TGenericParam> Get<TGenericParam>()
{
return Get<TGenericParam, GenericClass<TGenericParam>>();
}
}
Usage would then be like this:
var pool = new GenericClassPool();
pool.Add(new GenericClass<string> { Property = "String" });
pool.Add(new GenericClass<int> { Property = 0 });
GenericClass<string> firstObject = pool.Get<string>();
GenericClass<int> secondObject = pool.Get<int>();
The draw back of this solution is that you would need to create one pool class for each generic type you want to pool, so you potentially will have a lot of <className>Pool classes deriving from ObjectPool.
To make this usable, all real code needs to be in the ObjectPool class and only code that supplies the generic parameters remains in the derived classes.
I'd like to share my own pool classes. They have a similar API to the other code posted but are a bit more developed and flexible, in my totally biased opinion.
Single type object pool:
/// <summary>
/// Allows code to operate on a Pool<T> without casting to an explicit generic type.
/// </summary>
public interface IPool
{
Type ItemType { get; }
void Return(object item);
}
/// <summary>
/// A pool of items of the same type.
///
/// Items are taken and then later returned to the pool (generally for reference types) to avoid allocations and
/// the resulting garbage generation.
///
/// Any pool must have a way to 'reset' returned items to a canonical state.
/// This class delegates that work to the allocator (literally, with a delegate) who probably knows more about the type being pooled.
/// </summary>
public class Pool<T> : IPool
{
public delegate T Create();
public readonly Create HandleCreate;
public delegate void Reset(ref T item);
public readonly Reset HandleReset;
private readonly List<T> _in;
#if !SHIPPING
private readonly List<T> _out;
#endif
public Type ItemType
{
get
{
return typeof (T);
}
}
public Pool(int initialCapacity, Create createMethod, Reset resetMethod)
{
HandleCreate = createMethod;
HandleReset = resetMethod;
_in = new List<T>(initialCapacity);
for (var i = 0; i < initialCapacity; i++)
{
_in.Add(HandleCreate());
}
#if !SHIPPING
_out = new List<T>();
#endif
}
public T Get()
{
if (_in.Count == 0)
{
_in.Add(HandleCreate());
}
var item = _in.PopLast();
#if !SHIPPING
_out.Add(item);
#endif
return item;
}
public void Return( T item )
{
HandleReset(ref item);
#if !SHIPPING
Debug.Assert(!_in.Contains(item), "Returning an Item we already have.");
Debug.Assert(_out.Contains(item), "Returning an Item we never gave out.");
_out.Remove(item);
#endif
_in.Add(item);
}
public void Return( object item )
{
Return((T) item);
}
#if !SHIPPING
public void Validate()
{
Debug.Assert(_out.Count == 0, "An Item was not returned.");
}
#endif
}
Next, a multi-type pool.
There is no difference between using this class or using multiple Pool<T> yourself. But in some situations using this class will make code look cleaner, ie. eliminating if/else (type == foo) blocks.
/// <summary>
/// Represents a collection of pools for one or more object types.
/// </summary>
public class Pooler
{
private readonly List<IPool> _pools;
public Pooler()
{
_pools = new List<IPool>();
}
public void DefineType<T>(int initialCapacity, Pool<T>.Create createHandler, Pool<T>.Reset resetHandler)
{
var p = new Pool<T>(initialCapacity, createHandler, resetHandler);
_pools.Add(p);
}
public T Get<T>()
{
var p = GetPool(typeof (T));
if (p == null)
throw new Exception(string.Format("Pooler.Get<{0}>() failed; there is no pool for that type.", typeof(T)));
return ((Pool<T>)p).Get();
}
public void Return(object item)
{
var p = GetPool(item.GetType());
if (p == null)
throw new Exception(string.Format("Pooler.Get<{0}>() failed; there is no pool for that type.", item.GetType()));
p.Return(item);
}
private IPool GetPool(Type itemType)
{
foreach (var p in _pools)
{
if (p.ItemType == itemType)
{
return p;
}
}
return null;
}
}
As far as 'not having to specify the type parameter every time you access the pool', I often declare a concrete pool for a specific type that is frequently used.
public class GameObjectPool : Pool<GameObject>
{
public GameObjectPool(int initialCapacity)
:base(initialCapacity, CreateObject, ResetObject)
{
}
private GameObject CreateObject()
{ ... }
private GameObject ResetObject()
{ ... }
}
Then your code which was...
_pool = new Pool<GameObject>(10);
var obj = _pool.Get<GameObject>();
Can become...
_pool = new GameObjectPool(10);
var obj = _pool.Get();
Another option is...
using GameObjectPool=MyRootnamespace.Pool<GameObject>
Which can work if you have a ton of references to the pool, but they are all in the same code file.

Generic class to create concrete class automatically

Is there a way to take an interface, say:
/// <summary>
/// Interface containing operators which operate on T
/// </summary>
public interface IScalarOperators<T>
{
// Adds two T objects
IOperateScalar<T> OperatorAdd { get; }
// Subtracts two T objects
IOperateScalar<T> OperatorSubtract { get; }
// Multiplies two T objects
IOperateScalar<T> OperatorMultiply { get; }
}
// Class containing all the Scalar operators for a given T
class ScalarOperators<T> : IScalarOperators<T>
{
public IOperateScalar<T> OperatorAdd { get; private set; }
public IOperateScalar<T> OperatorSubtract { get; private set; }
public IOperateScalar<T> OperatorMultiply { get; private set; }
private ScalarOperators(IOperateScalar<T> add, IOperateScalar<T> subtract, IOperateScalar<T> multiply)
{
this.OperatorAdd = add;
this.OperatorSubtract = subtract;
this.OperatorMultiply = multiply;
}
public static ScalarOperators<bool> CreateBool()
{
return new ScalarOperators<bool>(new AddBool(), new SubtractBool(), new MultiplyBool());
}
public static ScalarOperators<int> CreateInt()
{
return new ScalarOperators<int>(new AddInt(), new SubtractInt(), new MultiplyInt());
}
// METHOD I WANT TO ADD
public static ScalarOperators<T> Create()
{
// if T == bool
// return CreateBool()
// if T == int
// return CreateInt()
// else (no definition available for T)
// return null
}
// I tried something like below, but it didn't work...
public static ScalarOperators<T> Create<T>() where T: bool
{ return CreateBool(); }
public static ScalarOperators<T> Create<T>() where T : int
{ return CreateInt(); }
public static ScalarOperators<T> Create<T>()
{ return null; }
}
Notice, I'd like a generic Create method which creates the correct set of operators, but I'm not sure how to do it.
I'd like to use it to remove the parameter from this method:
public static IMatrix<T> Add<T>(this IMatrix<T> matrix, IMatrix<T> other, IScalarOperators<T> operators)
{
JoinCells<T> joiner = new JoinCells<T>();
return joiner.Join(matrix, other, null, operators.OperatorAdd);
}
becomes
public static IMatrix<T> Add<T>(this IMatrix<T> matrix, IMatrix<T> other)
{
JoinCells<T> joiner = new JoinCells<T>();
return joiner.Join(matrix, other, null, ScalarOperators<T>.Create().OperatorAdd);
}
Thanks for any help! Mainly, I just don't want to have to pass the scalarOperator object to the extension method, I'd prefer to have a 'default' since it is unlikely that the ScalarOperators will change for any T that is defined.
i suggest making a factory of IScalarOperators instead of static class ( if your really need it to be static you could access it by static field ).
you could register them at app startup and get them by this example metod:
public IScalarOperators<T> Create<T>()
{
// check if exists in dictionary
return (ScalarOperators<T>)dict[typeof(T)];
}
dict will be of type Dictionary.
The adventage is that you could add new IScalarOperators during application grow only by creating new implementing class and registering it in factory, casting is a drawback. Also you will have better seperation of concerns and ( in my opinion ) cleaner code.
What you need to do is get the type of T.
Your Create method could be like this:
public static ScalarOperators<T> Create()
{
Type type = typeof(T);
if(type == typeof(bool))
return CreateBool()
if(type == typeof(int))
return CreateInt()
else
return null
}
There are a few things happening here that I think should be addressed. You're trying to segregate your custom operators from the types that they operate on, which is confusing, and you're trying to take the very broad concept of generics and then specialize them.
For the first one, you're always going to use the same operators for the same type (at least, you're never going to try and use bool operators on an int type). There's no reason to complicate things by having a separate class for them. For the latter, generic classes and generic methods are meant to work the same for any given T. Granted, you very well could get the typeof(T) in your static factory method and compare against that for several specific cases, and then you'll have to change that for every new T that you want to handle because of this overly complicated generic operand structure.
I would recommend creating a generic interface for your operands and then implementing a wrapper for those types instead. For example, int can be wrapped like this.
public interface IScalarOperators<T>
{
IScalarOperators<T> Add (IScalarOperators<T> rightSide);
IScalarOperators<T> Subtract (IScalarOperators<T> rightSide);
IScalarOperators<T> Multiply (IScalarOperators<T> rightSide);
T Unwrap();
}
public interface IMatrix<T> where T : IScalarOperators<T> { /* whatever */ }
public class CustomInt : IScalarOperators<CustomInt>
{
private readonly int number;
public CustomInt(int number) { this.number = number; }
public CustomInt Unwrap() { return this; }
public IScalarOperators<CustomInt> Add(IScalarOperators<CustomInt> rightSide) { return new CustomInt(number + rightSide.Unwrap().number); }
public IScalarOperators<CustomInt> Subtract(IScalarOperators<CustomInt> rightSide) { return new CustomInt(number - rightSide.Unwrap().number); }
public IScalarOperators<CustomInt> Multiply(IScalarOperators<CustomInt> rightSide) { return new CustomInt(number * rightSide.Unwrap().number); }
}
At that point, you can operate on an IMatrix<CustomInt> through the IScalarOperators<T> interface and perform any exposed operations you want. As a rough example, assuming you have an exposed accessor called array, you could say IScalarOperators<T> result = matrix.array[0, 0].Add(matrix.array[0, 1]); and get a representation back of adding the two together. You could then perform any further operations on that, and so on.

Store generic data in a non-generic class

I have a DataGridView that I want to use to store generic data. I want to keep a typed data list in the DataGridView class so that all of the sorts, etc. can be handled internally. But I don't want to have to set the type on the DataGridView since I won't know the data type until the InitializeData method is called.
public class MyDataGridView : DataGridView {
private List<T> m_data;
public InitializeData<T>(List<T> data) {
m_data = data;
}
... internal events to know when the datagrid wants to sort ...
m_data.Sort<T>(...)
}
Is this possible? If so, how?
If you won't know the type until you call InitializeData, then the type clearly can't be a compile-time part of the object.
Do you know everything you need to know about the sorting when you call InitializeData<T>? If so, how about you do something like:
private IList m_data;
private Action m_sorter;
public InitializeData<T>(List<T> data)
{
m_data = data;
// This captures the data variable. You'll need to
// do something different if that's not good enough
m_sorter = () => data.Sort();
}
Then when you need to sort later, you can just call m_sorter().
If you might sort on different things, you could potentially change it from an Action to Action<string> or whatever you'd need to be able to sort on.
If Jon's answer isn't sufficient, here's a more general (but more involved, and probably somewhat more confusing) approach:
/// <summary>
/// Allows a list of any type to be used to get a result of type TResult
/// </summary>
/// <typeparam name="TResult">The result type after using the list</typeparam>
interface IListUser<TResult>
{
TResult Use<T>(List<T> list);
}
/// <summary>
/// Allows a list of any type to be used (with no return value)
/// </summary>
interface IListUser
{
void Use<T>(List<T> list);
}
/// <summary>
/// Here's a class that can sort lists of any type
/// </summary>
class GenericSorter : IListUser
{
#region IListUser Members
public void Use<T>(List<T> list)
{
// do generic sorting stuff here
}
#endregion
}
/// <summary>
/// Wraps a list of some unknown type. Allows list users (either with or without return values) to use the wrapped list.
/// </summary>
interface IExistsList
{
TResult Apply<TResult>(IListUser<TResult> user);
void Apply(IListUser user);
}
/// <summary>
/// Wraps a list of type T, hiding the type itself.
/// </summary>
/// <typeparam name="T">The type of element contained in the list</typeparam>
class ExistsList<T> : IExistsList
{
List<T> list;
public ExistsList(List<T> list)
{
this.list = list;
}
#region IExistsList Members
public TResult Apply<TResult>(IListUser<TResult> user)
{
return user.Use(list);
}
public void Apply(IListUser user)
{
user.Use(list);
}
#endregion
}
/// <summary>
/// Your logic goes here
/// </summary>
class MyDataGridView
{
private IExistsList list;
public void InitializeData<T>(List<T> list)
{
this.list = new ExistsList<T>(list);
}
public void Sort()
{
list.Apply(new GenericSorter());
}
}
You should define delgates or an interface for any generic operations you need to perform at runtime. As Jon Skeet mentioned, you can't strongly-type your data grid if you don't know the types at compile time.
This is the way the framework does it. For example:
Array.Sort();
Has a few ways it can be used:
Send it an array of objects that implement IComparable or IComparable<T>
Send in a second parameter, which is a class that implements IComparer or IComparer<T>. Used to compare the objects for sorting.
Send in a second parameter, which is a Comparison<T> delegate that can be used to compare objects in the array.
This is an example of how you approach the problem. At its most basic level, your scenario can be solved by a strategy pattern, which is what Array.Sort() does.
If you need to sort by things dynamically at run time, I would create an IComparer class that takes the column you want to sort by as an argument in its constructor. Then in your compare method, use that column as the sort type.
Here is an example of how you would do it using some basic example classes. Once you have these classes set up, then you'd pass both into your data grid and use them where appropriate.
public class Car
{
public string Make { get; set; }
public string Model { get; set; }
public string Year { get; set; }
}
public class CarComparer : IComparer
{
string sortColumn;
public CarComparer(string sortColumn)
{
this.sortColumn = sortColumn;
}
public int Compare(object x, object y)
{
Car carX = x as Car;
Car carY = y as Car;
if (carX == null && carY == null)
return 0;
if (carX != null && carY == null)
return 1;
if (carY != null && carX == null)
return -1;
switch (sortColumn)
{
case "Make":
return carX.Make.CompareTo(carY.Make);
case "Model":
return carX.Model.CompareTo(carY.Model);
case "Year":
default:
return carX.Year.CompareTo(carY.Year);
}
}
}

Categories

Resources