如何将空单例添加到字典类型?
How to add an Empty singleton to Dictionary type?
module Extension =
type Dictionary<'T,'U> with
member this.Update (x: Dictionary<_,_>) =
for kvp in x do
this.[kvp.Key] <- kvp.Value
this
/// This is wrong too, I wanted to use
/// static let EmptyDictionary = Dictionary<'T,'U>()
static member EmptyDictionary = Dictionary<'T,'U>()
/// Should not modify it, needs to be readonly.
member this.Empty = Dictionary<'T,'U>.EmptyDictionary
为了模仿python字典update
的功能,我需要一个空字典,以避免每次不需要更新时都实例化一个新字典。 (我也可以使用 null
,但通常我会避免使用它。)
上面有警告说"a type constraint when 'T: equality is missing".
更新
以下演示了我的代码的用例。
假设 x
是一个字典,我可以通过 x.Update y
将它与 y
合并(更新 x
)
如果我不想更新x
但仍然需要传入一个y
,我可以使用x.Update x.Empty
我没有完全理解这个问题,但是写 new Dictionary<'K, 'V>()
似乎在 'K
上引入了 equality
约束。但是由于泛型类型本身不需要约束,这会导致不匹配。
所以,我不知道如何使用您使用的样式来修复定义,但无论如何我可能会使用一些不同的东西:
type Dictionary<'T,'U> with
member this.Update (x: IDictionary<_,_>) =
for kvp in x do
this.[kvp.Key] <- kvp.Value
this
module Dictionary =
let Empty<'T, 'U when 'T : equality> = Dictionary<'T,'U>()
这利用了这样一个事实,即您可以拥有一个与类型同名的模块,因此它添加了 Update
作为扩展名,但 Dictionary.Empty
是一个通用值。这让你写:
Dictionary.Empty.Update(dict [1, "hi"; 2, "bye"])
根据 F# 规范:
14.11 CLI 方法的附加约束
F# treats some CLI methods and types specially, because they are common in F# > programming and cause extremely difficult-to-find bugs. For each use of the > following constructs, the F# compiler imposes additional ad-hoc constraints:
x.Equals(yobj) requires type ty : equality for the static type of x
x.GetHashCode() requires type ty : equality for the static type of x
new Dictionary() requires A : equality, for any overload that does not > take an
IEqualityComparer
因此,如果您不打算改变空字典,那么您可以为 Dictionary<'K, 'V>
使用不同的构造函数重载并传递默认比较器。
此外,当前静态成员 EmptyDictionary
将在每次调用时 return 一个新的字典实例,我不确定这是不是故意的。您可以使用专用类型为每对类型参数存储空字典的唯一单例实例
open System.Collections.Generic
module Extension =
type EmptyDictionaryHolder<'T, 'U>() =
static let value = new Dictionary<'T, 'U>(EqualityComparer<'T>.Default)
static member Value: IDictionary<'T, 'U> = value :> _
type IDictionary<'T,'U> with
static member EmptyDictionary = EmptyDictionaryHolder<'T, 'U>.Value
member this.Update (x: IDictionary<_,_>) =
for kvp in x do
this.[kvp.Key] <- kvp.Value
this
member this.Empty = Dictionary<'T,'U>.EmptyDictionary
module Extension =
type Dictionary<'T,'U> with
member this.Update (x: Dictionary<_,_>) =
for kvp in x do
this.[kvp.Key] <- kvp.Value
this
/// This is wrong too, I wanted to use
/// static let EmptyDictionary = Dictionary<'T,'U>()
static member EmptyDictionary = Dictionary<'T,'U>()
/// Should not modify it, needs to be readonly.
member this.Empty = Dictionary<'T,'U>.EmptyDictionary
为了模仿python字典update
的功能,我需要一个空字典,以避免每次不需要更新时都实例化一个新字典。 (我也可以使用 null
,但通常我会避免使用它。)
上面有警告说"a type constraint when 'T: equality is missing".
更新
以下演示了我的代码的用例。
假设 x
是一个字典,我可以通过 x.Update y
y
合并(更新 x
)
如果我不想更新x
但仍然需要传入一个y
,我可以使用x.Update x.Empty
我没有完全理解这个问题,但是写 new Dictionary<'K, 'V>()
似乎在 'K
上引入了 equality
约束。但是由于泛型类型本身不需要约束,这会导致不匹配。
所以,我不知道如何使用您使用的样式来修复定义,但无论如何我可能会使用一些不同的东西:
type Dictionary<'T,'U> with
member this.Update (x: IDictionary<_,_>) =
for kvp in x do
this.[kvp.Key] <- kvp.Value
this
module Dictionary =
let Empty<'T, 'U when 'T : equality> = Dictionary<'T,'U>()
这利用了这样一个事实,即您可以拥有一个与类型同名的模块,因此它添加了 Update
作为扩展名,但 Dictionary.Empty
是一个通用值。这让你写:
Dictionary.Empty.Update(dict [1, "hi"; 2, "bye"])
根据 F# 规范:
14.11 CLI 方法的附加约束
F# treats some CLI methods and types specially, because they are common in F# > programming and cause extremely difficult-to-find bugs. For each use of the > following constructs, the F# compiler imposes additional ad-hoc constraints:
x.Equals(yobj) requires type ty : equality for the static type of x
x.GetHashCode() requires type ty : equality for the static type of x
new Dictionary() requires A : equality, for any overload that does not > take an IEqualityComparer
因此,如果您不打算改变空字典,那么您可以为 Dictionary<'K, 'V>
使用不同的构造函数重载并传递默认比较器。
此外,当前静态成员 EmptyDictionary
将在每次调用时 return 一个新的字典实例,我不确定这是不是故意的。您可以使用专用类型为每对类型参数存储空字典的唯一单例实例
open System.Collections.Generic
module Extension =
type EmptyDictionaryHolder<'T, 'U>() =
static let value = new Dictionary<'T, 'U>(EqualityComparer<'T>.Default)
static member Value: IDictionary<'T, 'U> = value :> _
type IDictionary<'T,'U> with
static member EmptyDictionary = EmptyDictionaryHolder<'T, 'U>.Value
member this.Update (x: IDictionary<_,_>) =
for kvp in x do
this.[kvp.Key] <- kvp.Value
this
member this.Empty = Dictionary<'T,'U>.EmptyDictionary