I\'m trying to implement a c++ like template with C# generics and policy pattern based on this answer
This is a sample of the pattern:
interface ISom
Usually, policies should not contain data. For example,
interface ISomePolicy
{
void _doSomething(T t, U u);
}
struct SomePolicyImplementation :
ISomePolicy,
ISomePolicy,
ISomePolicy
{
void ISomePolicy._doSomething(int t, int u)
=> Console.WriteLine("this is int, int");
void ISomePolicy._doSomething(int t, double u)
=> Console.WriteLine("this is int, double");
void ISomePolicy._doSomething(double t, double u)
=> Console.WriteLine("this is double, double");
}
static class SomePolicyExtension
{
public static void doSomething(this P policy, T t, U u)
where P : struct, ISomePolicy
=> policy._doSomething(t, u);
}
If you would like to combine policies and data then you may consider different interface
interface IEmbeddedPolicy
{
void _doSomething(U u);
}
class MyClass :
IEmbeddedPolicy,
IEmbeddedPolicy
{
public T Value { get; }
public MyClass(T value) { this.Value = value; }
void IEmbeddedPolicy._doSomething(int u)
=> Console.WriteLine("this is T, int");
void IEmbeddedPolicy._doSomething(double u)
=> Console.WriteLine("this is T, double");
}
static class EmbeddedPolicyExtension
{
public static void doSomething(this E embedded, U u)
where E : IEmbeddedPolicy
=> embedded._doSomething(u);
}
Or combination of these two concepts
class MySuperClass:
IEmbeddedPolicy,
IEmbeddedPolicy
where P: struct, ISomePolicy, ISomePolicy
{
public T Value { get; }
public MySuperClass(T value) { this.Value = value; }
void IEmbeddedPolicy._doSomething(int u)
=> new P()._doSomething(this.Value, u);
void IEmbeddedPolicy._doSomething(double u)
=> new P()._doSomething(this.Value, u);
}
Usage:
// independent policy
var policy = new SomePolicyImplementation();
policy.doSomething(5, 6);
policy.doSomething(5, 6.7);
policy.doSomething(5.3, 6.7);
// embedded policy
var my = new MyClass(54);
my.doSomething(5);
my.doSomething(89.7);
// combination
var x = new MySuperClass(53);
x.doSomething(9);
x.doSomething(18.3);