Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics f#获取带有约束的类型的泛型类型定义_Generics_F# - Fatal编程技术网

Generics f#获取带有约束的类型的泛型类型定义

Generics f#获取带有约束的类型的泛型类型定义,generics,f#,Generics,F#,这里是最终目标:通过名称从工厂获得一个新连接,如sofactory.CreateConnection(“MyDB”) 以下是我目前的代码: type IConnectionFactory = abstract member CreateConnection : unit -> IDbConnection type DefaultConnectionFactory<'t when 't : (new : unit -> 't) and 't :> IDbConne

这里是最终目标:通过名称从工厂获得一个新连接,如so
factory.CreateConnection(“MyDB”)

以下是我目前的代码:

type IConnectionFactory =
    abstract member CreateConnection : unit -> IDbConnection

type DefaultConnectionFactory<'t when 't : (new : unit -> 't) and 't :> IDbConnection> () =
    member this.CreateConnection () = new 't()

    interface IConnectionFactory with
        member this.CreateConnection () = this.CreateConnection() :> IDbConnection

type DefaultConnectionFactoryFactory() =
    member this.CreateConnectionFactory connectionType =
        if not (typeof<IDbConnection>.IsAssignableFrom connectionType)
        then invalidArg "connectionType" (sprintf "type %O is not assignable to IDbConnection" connectionType)

        let genericFactoryType = typedefof<DefaultConnectionFactory<_>>
        let factorytype = genericFactoryType.MakeGenericType([| connectionType |])
        Activator.CreateInstance(factorytype) :?> IConnectionFactory

type ConnectionFactory (connectionStrings : Dictionary<string, (IConnectionFactory * string)>) =
    let ConnectionStrings = connectionStrings

    member this.CreateConnection connectionStringName : 't :> IDbConnection =
        if ConnectionStrings.ContainsKey connectionStringName
        then
            let connectionFactory, connectionString = ConnectionStrings.Item connectionStringName
            let connection = connectionFactory.CreateConnection ()
            connection.ConnectionString <- connectionString
            connection :?> 't
        else invalidArg "dataSourceName" (sprintf "no data source found named %s" connectionStringName)
类型I连接工厂=
抽象成员CreateConnection:unit->IDbConnection
键入DefaultConnectionFactory't)和't:>IDbConnection>()=
成员this.CreateConnection()=新的't()
接口IConnectionFactory与
成员this.CreateConnection()=this.CreateConnection():>IDbConnection
类型DefaultConnectionFactoryFactory()=
成员this.CreateConnectionFactory connectionType=
如果不是(typeof.IsAssignableFrom connectionType)
然后是invalidArg“connectionType”(sprintf“类型%O不可分配给IDbConnection”connectionType)
让genericFactoryType=typedefof
让factorytype=genericFactoryType.MakeGenericType([| connectionType |])
Activator.CreateInstance(factorytype):?>IConnectionFactory
类型ConnectionFactory(ConnectionString:Dictionary)=
让ConnectionString=ConnectionString
成员this.createConnectionStringName:'t:>IDbConnection=
如果ConnectionString.ContainesKey ConnectionString名称
然后
让connectionFactory,connectionString=connectionString.Item connectionString名称
让连接=connectionFactory.CreateConnection()
connection.ConnectionString't
else invalidArg“dataSourceName”(sprintf“未找到名为%s的数据源”connectionStringName)
在这一行:

let genericFactoryType = typedefof<DefaultConnectionFactory<_>>
让genericFactoryType=typedefof
我得到这个错误: 为类型推断变量应用默认类型“IDbConnection”时,类型约束不匹配。泛型构造要求类型“IDBo连接”具有公共默认构造函数,考虑添加其他类型约束< /P> 我不知道如何解决它。。。任何其他的建议都是受欢迎的

这有点像你的建议。问题是
typedefof
DefaultConnectionFactory
上的约束需要实现
IDbConnection
并具有默认构造函数的类型。编译器不知道这种类型。所以,你必须提供一个。您可以使用
SqlConnection
,例如:

typedefof<DefaultConnectionFactory<System.Data.SqlClient.SqlConnection>>
typedefof

效果是一样的
typedefof
将返回无界类型
DefaultConnectionFactory
(以C语言表示),这是无法用F表示的。

ConnectionFactory
。。。太好了。如果你认为有更好的方法,我愿意接受建议……是的。。。。我发现这很管用,但似乎有些笨拙,好像我错过了一些简单的东西。我一直在想,必须有一种方法可以在不提供类型的情况下获得泛型类型定义。谢谢你的推荐。。。我在搜索时没有看到这一点。F#没有提供指定无界类型的方法。如果约束很小,并且通常解析为
obj
,则可以使用通配符(如您所拥有的)。