Я хочу получить класс от System.IO.BinaryWriter
и вызвать его конструктор с пользовательским Stream
, реализация которого захватывает аргумент конструктора производного типа. Для моей жизни я не могу понять, возможно ли это вообще. То, что я в основном пытаюсь сделать, немного обрезано быть MCV, являетсяПередайте конструктор конструктора замыкания на конструктор базового класса
type HashingBinaryWriter private
(hasher : System.Security.Cryptography.HashAlgorithm,
stream : System.IO.Stream) =
inherit System.IO.BinaryWriter(stream)
let unsupp() = raise(System.NotSupportedException())
let hash_stream =
{ new System.IO.Stream() with
member __.CanRead = false
member __.CanSeek = false
member __.CanWrite = true
member __.Length = unsupp()
member __.Position with get() = unsupp() and set(_) = unsupp()
member __.Seek(_,_) = unsupp()
member __.SetLength _ = unsupp()
member __.Read(_,_,_) = unsupp()
member __.Flush() =()
member __.Write(buffer, offset, count) =
hasher.TransformBlock(buffer, offset, count, null, 0) |> ignore
}
new(hasher) = new HashingBinaryWriter(hasher, hash_stream)
// Or, alternatively
new(hasher) as me = new HashingBinaryWriter(hasher, me.hash_stream)
Последней строка не может скомпилировать, потому что hash_stream
не определена, в любой форме. По-видимому, как указывает this answer, объем аргументов конструктора отличается от аргументов тела объявления класса, но мне нужно понять, что здесь происходит (и, если возможно, почему решение F # design design).
Действительно, я могу увидеть некоторые обходные пути (например, конвертировать hash_stream в частную собственность), но мой словарь идиом F # этого не хватает. Тогда мой второй вопрос: какой будет идиоматический способ сделать это.
Я подозреваю, идиоматическое способом было бы сделать 'hash_stream' связывает верхний уровень, который принял' hasher' в качестве аргумента –
@JohnPalmer: Имеет смысл, спасибо. – kkm