Skip to content

Instantly share code, notes, and snippets.

@airbreather
Created August 2, 2018 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save airbreather/e8b1f430fe81216e925bb3e863750707 to your computer and use it in GitHub Desktop.
Save airbreather/e8b1f430fe81216e925bb3e863750707 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
namespace M
{
public sealed class MemoizerBuilder<T1, T2, T3, T4, TOut>
{
private readonly Func<T1, T2, T3, T4, TOut> func;
private IEqualityComparer<T1> equalityComparer1;
private IEqualityComparer<T2> equalityComparer2;
private IEqualityComparer<T3> equalityComparer3;
private IEqualityComparer<T4> equalityComparer4;
public MemoizerBuilder(Func<T1, T2, T3, T4, TOut> func) => this.func = func ?? throw new ArgumentNullException(nameof(func));
public MemoizerBuilder<T1, T2, T3, T4, TOut> WithEqualityComparer1(IEqualityComparer<T1> equalityComparer1)
{
this.equalityComparer1 = equalityComparer1;
return this;
}
public MemoizerBuilder<T1, T2, T3, T4, TOut> WithEqualityComparer2(IEqualityComparer<T2> equalityComparer2)
{
this.equalityComparer2 = equalityComparer2;
return this;
}
public MemoizerBuilder<T1, T2, T3, T4, TOut> WithEqualityComparer3(IEqualityComparer<T3> equalityComparer3)
{
this.equalityComparer3 = equalityComparer3;
return this;
}
public MemoizerBuilder<T1, T2, T3, T4, TOut> WithEqualityComparer4(IEqualityComparer<T4> equalityComparer4)
{
this.equalityComparer4 = equalityComparer4;
return this;
}
public Func<T1, T2, T3, T4, TOut> Build()
{
var ec1 = this.equalityComparer1 ?? EqualityComparer<T1>.Default;
var ec2 = this.equalityComparer2 ?? EqualityComparer<T2>.Default;
var ec3 = this.equalityComparer3 ?? EqualityComparer<T3>.Default;
var ec4 = this.equalityComparer4 ?? EqualityComparer<T4>.Default;
bool hasValue = false;
(T1 v1, T2 v2, T3 v3, T4 v4, TOut vResult) lastCall = default;
return MyMemoized;
TOut MyMemoized(T1 v1, T2 v2, T3 v3, T4 v4)
{
if (!(hasValue &&
ec1.Equals(v1, lastCall.v1) &&
ec2.Equals(v2, lastCall.v2) &&
ec3.Equals(v3, lastCall.v3) &&
ec4.Equals(v4, lastCall.v4)))
{
hasValue = true;
lastCall = (v1, v2, v3, v4, this.func(v1, v2, v3, v4));
}
return lastCall.vResult;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment