和标题差不多。我有这个代码:
if (typeof(Option<string>).IsAssignableTo(typeof(Option<E>)))
{
return new Result<T, E>(None<T>(), (Option<E>)result.GetErr());
}
在此隐式转换运算符中:
public static implicit operator Result<T, E>(ResultT<T> result)
{
Debug.Assert(result.IsValid());
if (result.IsOk())
{
return new Result<T, E>(result.GetOk(), None<E>());
}
else
{
if (typeof(E).IsAssignableTo(typeof(Exception)))
{
return new Result<T, E>(None<T>(), ((E)Activator.CreateInstance(typeof(E), new object[] { result.GetErr().DefaultValue("") })!).Some());
}
/* Begin of the 1. Code Snippet */
else if (typeof(Option<string>).IsAssignableTo(typeof(Option<E>)))
{
return new Result<T, E>(None<T>(), (Option<E>)result.GetErr()); /*Result_T.GetErr() always returns Option<string>*/
/* End of 1. Code Snippet */
}
}
}
我的第一个片段的目标基本上是将
Result_T<T>
转换为 Result<T, string>
Result<T, E>
的构造函数期望以下内容:
private Result(Option<T> OkVal, Option<E> ErrVal)
{
value = OkVal;
error = ErrVal;
}
(我当然会检查结构是否有效)
然而,即使
Option<string>
理论上可以分配给 Option<E>
,编译器也会阻止它。
(
CS0030 Cannot convert type 'Toolkit.Option<string>' to 'Toolkit.Option<E>'
)
这背后的原因是什么?我怎样才能做到这一点?
编译器不会从运行时调用
Type.IsAssignableTo()
推断类型约束。
此外,它必须编译方法的每个分支,甚至是那些不会被采用的分支(由于运行时条件),并且它必须仅基于类型约束来执行此操作。然后 JIT 会将泛型编译为涵盖所有引用类型的单个机器代码实现。
泛型不是模板——在知道实际类型参数后,不会重做编译选择(重载解析、死代码删除)。