可区分联合中类型之间的转换
我有一个函数,它可以返回不同的类型,并且我使用可区分联合来实现此目的。我需要的是从可区分联合中的一种类型转换为另一种类型。 此外,某些类型可以转换为所有其他类型 (String),但某些类型只能转换为 String (MyCustomType)
为此,我添加了ConvertTo 到 ResultType
的成员方法:
type MyTypes =
| Boolean = 1
| Integer = 2
| Decimal = 3
| Double = 4
| String = 5
| MyCustomType = 6
type ResultType =
| Boolean of bool
| Integer of int
| Decimal of decimal
| Double of double
| String of string
| MyCustomType of MyCustomType
with
member this.ConvertTo(newType: MyTypes) =
match this with
| ResultType.Boolean(value) ->
match newType with
| MyTypes.Boolean ->
this
| MyTypes.Integer ->
ResultType.Integer(if value then 1 else 0)
...
| ResultType.MyCustomType(value) ->
match newType with
| MyTypes.MyCustomType ->
this
| MyTypes.String ->
ResultType.String(value.ToString())
| _ ->
failwithf "Conversion from MyCustomType to %s is not supported" (newType.ToString())
我不喜欢这样的构造,因为如果我添加更多类型,这需要我做很多更改:MyTypes、ResultType 以及 ConvertTo 成员函数中的多个位置。
任何人都可以为此类类型转换提出更好的解决方案吗?
提前致谢
I have a function, which can returns different types, and I use discriminated union for this. What I need, is to have conversion from one type in discriminated union to another type.
Also some of the types can be convertable to all other types (String), but some of the types can be converted only to String (MyCustomType)
For this I've added member method ConvertTo to the ResultType
:
type MyTypes =
| Boolean = 1
| Integer = 2
| Decimal = 3
| Double = 4
| String = 5
| MyCustomType = 6
type ResultType =
| Boolean of bool
| Integer of int
| Decimal of decimal
| Double of double
| String of string
| MyCustomType of MyCustomType
with
member this.ConvertTo(newType: MyTypes) =
match this with
| ResultType.Boolean(value) ->
match newType with
| MyTypes.Boolean ->
this
| MyTypes.Integer ->
ResultType.Integer(if value then 1 else 0)
...
| ResultType.MyCustomType(value) ->
match newType with
| MyTypes.MyCustomType ->
this
| MyTypes.String ->
ResultType.String(value.ToString())
| _ ->
failwithf "Conversion from MyCustomType to %s is not supported" (newType.ToString())
I don't like such construction, because if I add more types, this requires me to do many changes: MyTypes, ResultType and also in several places in the ConvertTo member function.
Can anybody suggest better solution for such types conversion?
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过稍微不同的设计,可以利用 System.Convert.ChangeType 以及可区分联合的构造函数实际上是函数的事实:
编辑:一旦添加更多自定义类型,这不会有太大帮助。
也许您应该让您的自定义类型实现
IConvertible
。然后,您可以从ConvertTo
中删除特殊情况代码,并完全依赖System.Convert.ChangeType
。每当添加新的自定义类型时,您仍然需要扩展每个自定义类型的
ToObject
实现。这是否真的比中央ConvertTo
函数更好是有争议的。With a slightly different design, it is possible to exploit
System.Convert.ChangeType
and the fact that the constructors of discriminated unions are actually functions:EDIT: Once you add more custom types, this will not help much.
Maybe you should make your custom types implement
IConvertible
. Then you can remove the special case code fromConvertTo
and completely rely onSystem.Convert.ChangeType
.You would still have to extend every custom type's
ToObject
implementation whenever you add a new custom type. Whether that really is better than a centralConvertTo
function is debatable.为什么要首先进行类型转换?可区分联合是隐藏类型信息直到您需要它并抽象复杂性的好方法。通常,您在使用此类型的函数中有一个匹配语句,然后仅在需要时才进行强制转换。
如果您尝试制作某种类型的解析器或语言引擎,那么您别无选择,只能定义所有转换或至少定义它们的错误状态。如果您不介意详细说明为什么/要使用它做什么,也许我可以建议另一种方法。
顺便说一句:F# 和 .NET 通常不支持返回类型的重载。
Why are you wanting to do type conversion to begin with? Discriminated Unions are a good way of hiding type information until you need it and abstract complexity away. Generally you have a match statement in a function that consumes this type and then you only cast if you need to.
If you're trying to make some type of parser or language engine then you have no choice but to define all the cast or at least their error states. If you wouldn't mind elaborating on why / what you would use this for, maybe I could suggest another approach.
An aside: F# and .NET in general doesn't support overloading of return types.