What I want to do is change how a C# method executes when it is called, so that I can write something like this:
[Distributed]
public DTask Solve
I know it is not the exact answer to your question, but the usual way to do it is using factories/proxy approach.
First we declare a base type.
public class SimpleClass
{
public virtual DTask Solve(int n, DEvent callback)
{
for (int m = 2; m < n - 1; m += 1)
if (m % n == 0)
return false;
return true;
}
}
Then we can declare a derived type (call it proxy).
public class DistributedClass
{
public override DTask Solve(int n, DEvent callback)
{
CodeToExecuteBefore();
return base.Slove(n, callback);
}
}
// At runtime
MyClass myInstance;
if (distributed)
myInstance = new DistributedClass();
else
myInstance = new SimpleClass();
The derived type can be also generated at runtime.
public static class Distributeds
{
private static readonly ConcurrentDictionary pDistributedTypes = new ConcurrentDictionary();
public Type MakeDistributedType(Type type)
{
Type result;
if (!pDistributedTypes.TryGetValue(type, out result))
{
if (there is at least one method that have [Distributed] attribute)
{
result = create a new dynamic type that inherits the specified type;
}
else
{
result = type;
}
pDistributedTypes[type] = result;
}
return result;
}
public T MakeDistributedInstance()
where T : class
{
Type type = MakeDistributedType(typeof(T));
if (type != null)
{
// Instead of activator you can also register a constructor delegate generated at runtime if performances are important.
return Activator.CreateInstance(type);
}
return null;
}
}
// In your code...
MyClass myclass = Distributeds.MakeDistributedInstance();
myclass.Solve(...);
The only performance loss is during construction of the derived object, the first time is quite slow because it will use a lot of reflection and reflection emit. All other times, it is the cost of a concurrent table lookup and a constructor. As said, you can optimize construction using
ConcurrentDictionary>.