无法隐式转换 IEnumerable
Cannot implicitly cast IEnumerable
我有一个 class 指示对方法的调用是成功(有值)还是有错误。
internal sealed class ValueOrError<TValue>
{
public bool IsError => _error is not null;
public bool IsSuccess => !IsError;
private TValue? _value;
private Error? _error;
private ValueOrError() { }
public TValue? Value =>
_error is null
? _value
: throw new InvalidOperationException("Is an error type");
public Error Error => _error ?? throw new InvalidOperationException("Not an error type");
public static ValueOrError<TValue> FromValue(TValue? result) =>
new ValueOrError<TValue> { _value = result };
public static ValueOrError<TValue> FromError(Error error) =>
new ValueOrError<TValue> { _error = error ?? throw new ArgumentNullException(nameof(error)) };
public static implicit operator ValueOrError<TValue>(TValue value) => ValueOrError<TValue>.FromValue(value);
public static implicit operator ValueOrError<TValue>(Error error) => ValueOrError<TValue>.FromError(error);
}
除非 TValue
是 IEnumerable<T>
.
,否则我可以隐式转换
// Works
ValueOrError<int> x = 1;
// Fails
ValueOrError<IEnumerable<int>> y = Enumerable.Empty<int>();
无法将类型 'System.Collections.Generic.IEnumerable' 隐式转换为 'AppLayer.ValueOrError'
但是,我可以创建“长途”类型的结果
c# // Works ValueOrError<IEnumerable<int>>.FromValue(Enumerable.Empty<int>());
如果有用,Error
的来源是
public class Error
{
public string Message { get; }
[JsonConstructor]
public Error(string message)
{
Message = message ?? throw new ArgumentNullException(nameof(message));
}
}
如果您查看有关 User-defined 转换的 C# 规范:
使用隐式或显式运算符的先决条件之一是
Neither S₀ nor T₀ is an interface_type.
因此,如果您真的想使用隐式转换,则必须将接口引用转换为 class 引用(例如通过调用 .ToArray()
)。
或者您可以创建静态 class 以利用类型推断:
internal static class ValueOnError
{
public static ValueOnError<TValue> FromValue<TValue>(TValue value)
=> ValueOnError<TValue>.FromValue(value);
}
那你就可以写
var y = ValueOnError.FromValue(Enumerable.Empty<int>());
我有一个 class 指示对方法的调用是成功(有值)还是有错误。
internal sealed class ValueOrError<TValue>
{
public bool IsError => _error is not null;
public bool IsSuccess => !IsError;
private TValue? _value;
private Error? _error;
private ValueOrError() { }
public TValue? Value =>
_error is null
? _value
: throw new InvalidOperationException("Is an error type");
public Error Error => _error ?? throw new InvalidOperationException("Not an error type");
public static ValueOrError<TValue> FromValue(TValue? result) =>
new ValueOrError<TValue> { _value = result };
public static ValueOrError<TValue> FromError(Error error) =>
new ValueOrError<TValue> { _error = error ?? throw new ArgumentNullException(nameof(error)) };
public static implicit operator ValueOrError<TValue>(TValue value) => ValueOrError<TValue>.FromValue(value);
public static implicit operator ValueOrError<TValue>(Error error) => ValueOrError<TValue>.FromError(error);
}
除非 TValue
是 IEnumerable<T>
.
// Works
ValueOrError<int> x = 1;
// Fails
ValueOrError<IEnumerable<int>> y = Enumerable.Empty<int>();
无法将类型 'System.Collections.Generic.IEnumerable' 隐式转换为 'AppLayer.ValueOrError'
但是,我可以创建“长途”类型的结果
c# // Works ValueOrError<IEnumerable<int>>.FromValue(Enumerable.Empty<int>());
如果有用,Error
的来源是
public class Error
{
public string Message { get; }
[JsonConstructor]
public Error(string message)
{
Message = message ?? throw new ArgumentNullException(nameof(message));
}
}
如果您查看有关 User-defined 转换的 C# 规范:
使用隐式或显式运算符的先决条件之一是
Neither S₀ nor T₀ is an interface_type.
因此,如果您真的想使用隐式转换,则必须将接口引用转换为 class 引用(例如通过调用 .ToArray()
)。
或者您可以创建静态 class 以利用类型推断:
internal static class ValueOnError
{
public static ValueOnError<TValue> FromValue<TValue>(TValue value)
=> ValueOnError<TValue>.FromValue(value);
}
那你就可以写
var y = ValueOnError.FromValue(Enumerable.Empty<int>());