TokugawaTakeshi / CrossPlatformOrganizerAppplication

0 stars 0 forks source link

`NumericMaximumInputtedValueValidationRule`数型不問にする #59

Open TokugawaTakeshi opened 1 year ago

TokugawaTakeshi commented 1 year ago

現在下記のクラスはuintMaximalValueにしか対応されていないが、新しいクラスを作らずにその他の数型のデータも取り扱える様にできませんが?

public class NumericMaximumInputtedValueValidationRule : InputtedValueValidation.IRule
{

  public interface ILocalization
  {

    public Func<ErrorMessage.TemplateVariables, string> ErrorMessageBuilder { get; }

    static class ErrorMessage
    {

      public struct TemplateVariables
      {
        public uint MaximalValue { get; init; }
        public string RawValue { get; init; }
      }

    }

  }

  public static ILocalization Localization = new NumericMaximumInputtedValueValidationRuleEnglishLocalization();

  public bool MustFinishValidationIfValueIsInvalid { get; init; }

  public uint MaximalValue { get; init; }
  public Func<ILocalization.ErrorMessage.TemplateVariables, string>? ErrorMessageBuilder { get; init; }
  public string? ErrorMessage { get; init; }

  public InputtedValueValidation.IRule.CheckingResult Check(object rawValue) =>
      new()
      {
        ErrorMessage = rawValue is uint uintValue && uintValue <= this.MaximalValue ? 
          null : 
          this.buildErrorMessage(
            new ILocalization.ErrorMessage.TemplateVariables
              {
                RawValue = rawValue.ToString() ?? "null", MaximalValue = this.MaximalValue
              }
          )
      };

  private string buildErrorMessage(ILocalization.ErrorMessage.TemplateVariables templateVariables)
  {

    if (this.ErrorMessageBuilder is not null)
    {
      return this.ErrorMessageBuilder(templateVariables);
    }

    if (this.ErrorMessage is not null)
    {
      return this.ErrorMessage;
    }

    return NumericMaximumInputtedValueValidationRule.Localization.ErrorMessageBuilder(templateVariables);

  }

}

型に依存の部分は主にrawValue is uint uintValue && uintValue <= this.MaximalValueです。

gummoni commented 1 year ago

新しいクラスを作らずに他の数値型に対応する方法は、 object型で受け取って中で

if (value is Type foo) ...

のように解析を行うか、 ジェネリッククラス<T>で型を外部から設定できるようにするかの2択になります。

私が実装する場合はインターフェイスを定義して、各々の数字に対応する型クラスを実装していく感じです。