该参数的使用方式限制它始终为 DerrivedType
The parameter has been used in a way that constrains it to always be DerrivedType
您好,我刚开始使用 F# 编程,但遇到了类型问题。
我有这个功能:
member private this.UpdateStats<'T when 'T :> StatisticsBase>(passed: bool, stats: 'T) =
//more stuff..
stats
我是这样称呼它的:
this.UpdateStats<GroupStats>(true, GroupStats(Id = Guid.NewGuid()))
编译器说:
该参数的使用方式限制它始终为 GroupStats。
GroupStats 继承自 StatisticsBase。我必须做什么才能使该函数可用于从 StatisticsBase 继承的所有实体?
类型:
[<AllowNullLiteral>]
type StatisticsBase() =
member val Id = String.Empty with get,set
[<AllowNullLiteral>]
type GroupStats() =
inherit Stats()
StatisticsBase 实际上继承自 C# 类型并在存储库中使用,但我可以使用上面的代码重现错误
经过多次反复,我们已经能够确定您的实际非工作代码是这样的(未来提示:提供更多信息):
type SomeType() =
member this.M2() =
this.M<GroupStats>(true, GroupStats())
member private this.M<'T when 'T :> Stats>(x: bool, t: 'T) =
t
此代码确实会产生所描述的错误。这是因为 F# 类型推断是从上到下、从左到右进行的。但有一个例外:类(和其他相互递归的定义组)获得两次类型推断 - 首先是签名,然后是主体。
当编译器第一次遇到 M2
的主体时,它确定方法 M
必须 return GroupStats
。后来,当编译器遇到M
的主体时,它看到M
的return值与参数t
相同,这意味着M
] 必须 return 'T
。但是由于编译器已经通过检查 M2
的主体知道 M
必须 return GroupStats
,因此 'T
必须是 GroupStats
.
如果M
定义在M2
之前,则不会发生这种情况:在这种情况下,类型推断将首先遇到M
的主体并正确确定其return 类型为 'T
,它将与 M2
的正文匹配,并且不会有问题。
从上面可以得出两种解决方案:首先,您可以在M2
之前定义M
。其次,您可以明确指定 M
:
的 return 类型
member private this.M<'T when 'T :> Stats>(x: bool, t: 'T): 'T =
t
这样,它的return类型在第一遍后就知道了,问题就消失了。
您好,我刚开始使用 F# 编程,但遇到了类型问题。 我有这个功能:
member private this.UpdateStats<'T when 'T :> StatisticsBase>(passed: bool, stats: 'T) =
//more stuff..
stats
我是这样称呼它的:
this.UpdateStats<GroupStats>(true, GroupStats(Id = Guid.NewGuid()))
编译器说:
GroupStats 继承自 StatisticsBase。我必须做什么才能使该函数可用于从 StatisticsBase 继承的所有实体?
类型:
[<AllowNullLiteral>]
type StatisticsBase() =
member val Id = String.Empty with get,set
[<AllowNullLiteral>]
type GroupStats() =
inherit Stats()
StatisticsBase 实际上继承自 C# 类型并在存储库中使用,但我可以使用上面的代码重现错误
经过多次反复,我们已经能够确定您的实际非工作代码是这样的(未来提示:提供更多信息):
type SomeType() =
member this.M2() =
this.M<GroupStats>(true, GroupStats())
member private this.M<'T when 'T :> Stats>(x: bool, t: 'T) =
t
此代码确实会产生所描述的错误。这是因为 F# 类型推断是从上到下、从左到右进行的。但有一个例外:类(和其他相互递归的定义组)获得两次类型推断 - 首先是签名,然后是主体。
当编译器第一次遇到 M2
的主体时,它确定方法 M
必须 return GroupStats
。后来,当编译器遇到M
的主体时,它看到M
的return值与参数t
相同,这意味着M
] 必须 return 'T
。但是由于编译器已经通过检查 M2
的主体知道 M
必须 return GroupStats
,因此 'T
必须是 GroupStats
.
如果M
定义在M2
之前,则不会发生这种情况:在这种情况下,类型推断将首先遇到M
的主体并正确确定其return 类型为 'T
,它将与 M2
的正文匹配,并且不会有问题。
从上面可以得出两种解决方案:首先,您可以在M2
之前定义M
。其次,您可以明确指定 M
:
member private this.M<'T when 'T :> Stats>(x: bool, t: 'T): 'T =
t
这样,它的return类型在第一遍后就知道了,问题就消失了。