阅读所有建议的相关问题后,我找不到我的问题的答案。给您写信,希望您能尽快回答,并宽容地判断我在这方面的知识不足。
我有一个类型来体现一个函数定义:
type FunctionDefinition<'a>(exec:int->(Data.Reader->'a)) =
member x.Exec = exec
member x.ReturnType = typeof<'a>
如您在此处看到的,exec
应该是一个接受一个int
参数的函数,并返回另一个接受一个Data.Reader
参数并返回'a
类型的值的函数(例如一个枯燥的短语!)。 Data.Reader
的定义在这里无关紧要。另外,我有一个字典来保留
string->FunctionDefinition
对,如下所示:let FUNCTIONS = new Generic.Dictionary<string, FunctionDefinition<obj>>()
FunctionDefinition
中的FUNCTIONS
实例将拥有几种类型的函数,这就是为什么它是FunctionDefinition<obj>
的原因(我相信这是邪恶的根源,但我无法避免,因此我在这里)。然后,我将一些函数包装在
FunctionDefinition
中并放入FUNCTIONS
中:/// Function definitions
let unchanged (id:int) =
let mutable last = null
fun (reader:Data.Reader) ->
if last = null then
false
else
let cur = reader.GetValue(id)
let ret = last.Equals(cur)
last <- cur
ret
let changed (id:int) =
let un = unchanged id
fun(reader:Data.Reader) ->
not (un reader)
let dummyfortesting (id:int) =
fun(x) -> "yam-yam"
我以为我可以将这些功能添加到我的字典中,但是……没什么!如下代码:FUNCTIONS.Add("unchanged", new FunctionDefinition<bool>(unchanged))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTIONS.Add("changed", new FunctionDefinition<bool>(changed))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FUNCTIONS.Add("dummy", new FunctionDefinition<string>(dummyfortesting))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
给出明确的错误消息:// The type 'obj' does not match the type 'bool'
// The type 'obj' does not match the type 'bool'
// The type 'obj' does not match the type 'string'
而以下是正确的:typeof<bool>.isSubclassOf(typeof<obj>) // -> true
这是不公平的,不是吗?问题是
如何实例化
FUNCTIONS
字典以容纳几个FunctionDefinition<bool>
,FunctionDefinition<string>
实例?还是除了为返回不同类型的函数保留通用
FunctionDefinition
类型之外,还有其他解决方案吗?一种解决方案是将所需的类型作为参数传递给
FunctionDefinition
的构造函数,如下所示:type FunctionDefinition(typ:System.Type, exec:int->(Data.Reader->???)) =
member x.Exec = exec
member x.ReturnType = typ
但是这里不清楚如何声明exec
。我希望我足够清楚。
非常感谢。
您忠诚的,
h
最佳答案
您正在创建的字典需要保存相同类型的值。如果使用不同的类型参数创建两个FunctionDefinition<'T>
值,则它们将是不同的类型,因此无法将它们组合在一个字典中。
解决此的一种方法是定义一个非通用接口(interface),并创建一个存储该接口(interface)值的字典(将由所有通用FunctionDefinition<'T>
对象实现)
type IFunctionDefinition =
abstract ReturnType : System.Type
abstract Exec : int -> (Reader -> obj)
let dict = new Dictionary<string, IFunctionDefinition>()
Exec
函数必须返回obj
,因为在将函数存储在(同质)字典中之后无法恢复类型信息。然后,您的具体类型可以实现接口(interface):type FunctionDefinition<'a>(exec:int->(Reader->'a)) =
member x.Exec = exec
interface IFunctionDefinition with
member x.ReturnType = typeof<'a>
member x.Exec n = fun rdr -> box (exec n rdr)
现在,您可以将创建的函数定义添加到字典中,因为它们实现了 public 接口(interface):
let foo = FunctionDefinition<int>(fun _ _ -> 42)
dict.Add("foo", foo)
另一种方法将是使类型定义为非泛型的。使用字典中的函数确定它们返回的值时,需要进行一些动态类型测试。您可以通过使用已区分的联合作为返回类型来使其明确:
type ResultType =
| String of string
| Bool of bool
// etc. for all supported return types