Я почти успешно обновил свою библиотеку, чтобы она была «осведомлена о нуле». Однако следующий код доставляет мне неприятности.
public static Result<string, TValid> ResultMustBe<TValid>
(
this TValid self,
params Func<TValid, Result<string, TValid>>[] validators
)
{
var caller = new StackFrame(1)?.GetMethod()?.DeclaringType?.FullName ?? "?";
if (!validators.Any())
{
throw new ArgumentException($"No validators provided for EitherMustBe in {caller}");
}
Result<string, TValid>? result = null;
foreach (var validator in validators)
{
try
{
result = validator(self);
if (result is Result<string, TValid>.Invalid left)
{
return Result<string, TValid>.MakeInvalid(left.Error.Replace("<<caller>>", caller));
}
}
catch (Exception ex)
{
throw new ValidationException($"Uncaught exception occured while validating {caller}", ex);
}
}
// Warning produced here
return result! as Result<string, TValid>.Valid;
}
public abstract class Result<TInvalid, TValid>
{
public static Valid MakeValid(TValid data)
{
return new Valid(data);
}
public static Invalid MakeInvalid(TInvalid error)
{
return new Invalid(error);
}
public abstract bool IsValid { get; }
public class Invalid : Result<TInvalid, TValid>
{
public TInvalid Error { get; }
public override bool IsValid => false;
public Invalid(TInvalid error)
{
Error = error;
}
}
public class Valid : Result<TInvalid, TValid>
{
public TValid Data { get; }
public override bool IsValid => true;
public Valid(TValid data)
{
Data = data;
}
}
}
Компилятор выдает мне предупреждение для return с [CS8603] Possible null reference return
, которое я могу понять, видя, как я инициализирую result
с null
. Однако метод никогда не может вернуть ноль, result
всегда будет последним возвращаемым значением из validator
.
Является ли pragma warning diable
моим единственным вариантом здесь, или я что-то упустил? Я должен добавить, что я не хочу менять тип возвращаемого значения моего метода Either (как опять-таки, он должен быть нулевым).
Редактировать : Переименован класс Either
на Result
(тип возврата), так как это отвлекает от вопроса. Также включен код для класса. Как было сказано в комментариях, этот тип действительно был вдохновлен FP, если быть точным, от Kotlin Arrow, но никогда не предполагалось, что он будет вести себя именно так.