Я пытаюсь создать фабрику, где я могу возвращать тип класса на основе типа класса, переданного в фабрику. На основе этого я затем вызываю метод для возвращенного класса со связанной, но отдельной подписью. Я пытаюсь использовать делегат для подписи метода, но получаю ошибки компиляции. См. Следующие фрагменты кода:
Политики:
public interface IPolicy
{
Guid Id { get; }
TypeEnum NetworkType { get; }
}
public class PPOPolicy : IPolicy
{
// PPO specific properties...
}
public class HMOPolicy : IPolicy
{
// HMO specific properties...
}
Калькуляторы, требующие определенного типа c IPolicy:
public static class PpoCalculator
{
public static bool TryBuildEstimate(Treatment treatment, PPOPolicy policy,
out InsurancePolicyEstimate estimate
)
{
// implementation...
}
}
public static class HmoCalculator
{
public static bool TryBuildEstimate(Treatment treatment, HMOPolicy policy,
out InsurancePolicyEstimate estimate
)
{
// implementation...
}
}
Телефонный код:
public static class BenefitEstimator
{
public static IEnumerable<InsurancePolicyEstimate> EstimateBenefit(Treatment treatment,
IReadOnlyList<IPolicy> policies
)
{
var primaryPolicy = policies.First();
var calculated = Calculate(primaryPolicy, treatment, out var primaryEstimate);
}
private static bool Calculate(IPolicy policy, Treatment treatment, out InsurancePolicyEstimate estimate)
{
switch (policy)
{
case PPOPolicy ppoPolicy:
return CalculatorFactory.GetCalculator(ppoPolicy).Invoke(treatment, ppoPolicy, out estimate);
case HMOPolicy hmoPolicy:
return CalculatorFactory.GetCalculator(hmoPolicy).Invoke(treatment, hmoPolicy, out estimate);
default:
throw new ArgumentOutOfRangeException(nameof(policy));
}
}
Это фабрика:
public static class CalculatorFactory
{
public static TryBuildEstimate GetCalculator(IPolicy policy)
{
switch (policy)
{
case TreatmentInsurancePolicy treatmentInsurancePolicy:
return PpoCalculator.TryBuildEstimate;
case DhmoInsurancePolicy dhmoInsurancePolicy:
return HmoCalculator.TryBuildEstimate;
default:
throw new ArgumentOutOfRangeException();
}
}
}
Это мой делегат:
public delegate bool TryBuildEstimate(Treatment treatment, IPolicy policy, out InsurancePolicyEstimate estimate);
Я пробовал сделать делегата generi c like TryBuildEstimate<in T>(Treatment treatment, T policy, out InsurancePolicyEstimate estimate) where T : IPolicy
но тогда подписи не совпадают с таковыми в калькуляторе.
Есть ли способ заставить эту работу работать или способ лучше структурировать весь этот сценарий? В конечном итоге я пытаюсь создать класс оценщика, который может получить любой тип калькулятора в зависимости от типа политики и вернуть подпись оценки bool / out.