kvb 的变体(它不会做完全相同的事情,因为它假设类型测试成功)可以修改以产生类似的模式:
let (|Value|_|) x value =
match box value with
| :? 'T as y when x = y -> Some()
| _ -> None
但是,存在细微的性能差异。原始的活动模式转换为:
public static FSharpOption<T> |Value|_|<a, T>(a value)
{
object obj = value;
if (!LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric<T>(obj))
{
return null;
}
return FSharpOption<T>.Some((T)((object)obj));
}
也就是说,它会进行类型测试和强制转换。它的用法(match x with Value "" -> ...
)转换为:
FSharpOption<string> fSharpOption = MyModule.|Value|_|<object, string>(obj);
if (fSharpOption != null && string.Equals(fSharpOption.Value, ""))
{
...
}
最值得注意的是,从模式返回的类型化值使用典型的编译器转换模式匹配(string.Equals
用于字符串)。
更新后的模式转换为:
public static FSharpOption<Unit> |Value|_|<T, a>(T x, a value)
{
object obj = value;
if (LanguagePrimitives.IntrinsicFunctions.TypeTestGeneric<T>(obj))
{
T y = (T)((object)obj);
T y3 = y;
if (LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<T>(x, y3))
{
T y2 = (T)((object)obj);
return FSharpOption<Unit>.Some(null);
}
}
return null;
}
它使用泛型相等性并且比匹配文字效率低。用法稍微简单一些,因为模式中包含了相等性:
FSharpOption<Unit> fSharpOption = MyModule.|Value|_|<string, object>("", obj);
if (fSharpOption != null)
{
...
}
无论如何,它有效。但我更喜欢原版。