Могу ли я использовать ключевое слово 'use' с объектными выражениями? - PullRequest
1 голос
/ 26 апреля 2011

Я использую объектное выражение для реализации двух интерфейсов.Один из интерфейсов является IDisposable.Я ожидал, что смогу использовать ключевое слово 'use' с результатами этого выражения объекта, но получаю ошибку:

Несоответствие ограничения типа.Тип IConnMan несовместим с типом IDisposable. Тип 'IConnMan' несовместим с типом 'IDisposable'

Почему я получаю эту ошибку?

let connectionstring = "context connection=true"
let connman () = 
   let conn = new SqlConnection(connectionstring)
   conn.Open()
   { new IConnMan with
        member x.Connect () = conn
        member x.Disconnect c = ()
     interface IDisposable with
        member x.Dispose() = 
           conn.Close()
           conn.Dispose()
   }

 ... 

 let f() = 
    use cn = connman() // <-- Error!

Ответы [ 2 ]

4 голосов
/ 26 апреля 2011

объектное выражение может иметь только один тип. Тип - это тип первого (основного) реализованного интерфейса - в вашем случае это тип IconnMan. F # не позволяет вам использовать use, потому что он статически не знает, что результат функции connman равен IDisposable.

Вы можете создавать интерфейсы в выражении объекта в обратном порядке:

let connman () = 
  let conn = new SqlConnection(connectionstring)
  conn.Open()
  { new IDisposable with
      member x.Dispose() = 
          conn.Close()
          conn.Dispose()
    interface IConnMan with
      member x.Connect () = conn
      member x.Disconnect c = () }

Тогда вы могли бы написать use cn = connman(), но вы не могли бы использовать функции IConnMan без приведения (это по сути то же самое, что делать то, что предлагает Desco). Я не думаю, что есть какое-то хорошее решение этой проблемы.

Может ли ваш IConnMan интерфейс наследовать от IDisposable?

3 голосов
/ 26 апреля 2011

F # spec говорит:

Выражения объекта статически проверяются следующим образом.Сначала проверяются ty0-tyn, и все они должны быть именованными типами.Общий тип выражения является ty0 и утверждается, что он равен начальному типу выражения.Однако, если ty0 является типом, эквивалентным типу System.Object, и где ty1 существует, тогда вместо общего типа используется тип ty1.

, так что вы можете использовать тесты типов и откаты или изменить последовательность реализуемых интерфейсов, чтобыIDisposable будет первым

let f() = 
    use cn = connman() :?> IDisposable
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...