首页 文章

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

提问于
浏览
1

这是最终目标:通过名称从工厂获取新连接 factory.CreateConnection<SqlConnection>("my db")

到目前为止,这是我的代码:

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)

在这条线上:

let genericFactoryType = typedefof<DefaultConnectionFactory<_>>

我收到此错误:为类型推断变量应用默认类型“IDbConnection”时,键入约束不匹配 . 泛型构造要求类型“IDbConnection”具有公共默认构造函数 . 考虑添加其他类型约束

我不确定如何解决它...欢迎任何其他建议

1 回答

  • 3

    这与this question有关 . 问题是 typedefof<DefaultConnectionFactory<_>> . DefaultConnectionFactory 上的约束需要一个实现 IDbConnection 的类型,并且具有默认构造函数 . 编译器知道没有这种类型 . 所以,你必须提供一个 . 你可以使用 SqlConnection ,例如:

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

    效果是一样的 . typedefof 将返回无界类型 DefaultConnectionFactory<> (以C#术语表示),这在F#中无法表达 .

相关问题