通过引用expression.parameter传递system.io.stream [英] Pass a system.io.stream by reference to a expression.parameter
问题描述
我有一段代码应该使用Linq Expressions将运行时编译lambda函数放在一起,将事件保存到流中。
(如果你想使用不同的序列化技术,这是为了允许通过注入换掉函数)
代码是: -
I have a piece of code that is supposed to use Linq Expressions to put together a "compiled at run time" lambda function to persist events to a stream.
(This is to allow the function to be swapped out by injection if you want to use a different serialisation technology)
The code is:-
Public Function CreateDefaultSaveToStreamFunction(Of TEvent As {New, IEvent})() As Func(Of TEvent, System.IO.Stream, Long)
'otherwise build the function by reflection
Dim valueParameter As ParameterExpression =
Expression.Parameter(GetType(TEvent), "eventToSerialise")
'Type to be populated...
Dim streamParameter As ParameterExpression =
Expression.Parameter(GetType(System.IO.Stream), "stream")
Dim sequenceParameter As ParameterExpression =
Expression.Variable(GetType(Long), "sequence")
Dim innerBlockExpressions As New List(Of Expression)()
'Dim sequence As Long
innerBlockExpressions.Add(Expression.Assign(sequenceParameter,
Expression.[New](GetType(Long))))
'Dim bf As New BinaryFormatter()
Dim binaryFormatterParameter As ParameterExpression =
Expression.Variable(GetType(System.Runtime.Serialization.Formatters.Binary.BinaryFormatter), "bf")
innerBlockExpressions.Add(Expression.Assign(binaryFormatterParameter,
Expression.[New](GetType(System.Runtime.Serialization.Formatters.Binary.BinaryFormatter))))
'Public Sub Serialize(serializationStream As Stream, graph As Object)
Dim serialiseMethod As MethodInfo = GetType(System.Runtime.Serialization.Formatters.Binary.BinaryFormatter).GetMethod("Serialize", {GetType(System.IO.Stream), GetType(Object)})
innerBlockExpressions.Add(
Expression.Call(binaryFormatterParameter, serialiseMethod, {streamParameter, valueParameter})
)
'sequence = streamParameter.Position
innerBlockExpressions.Add(Expression.Assign(sequenceParameter,
Expression.PropertyOrField(streamParameter, "Position")
)
)
'Return sequenceParameter
innerBlockExpressions.Add(sequenceParameter)
Dim innerBlock As BlockExpression = Expression.Block({valueParameter, streamParameter, sequenceParameter, binaryFormatterParameter},
innerBlockExpressions.AsEnumerable())
Dim toStreamBody As BlockExpression = Expression.Block(
New ParameterExpression() {valueParameter, streamParameter},
innerBlock)
Dim retLambda As LambdaExpression = Expressions.Expression(Of EventSerializer(Of TEvent).SaveToStream).Lambda(toStreamBody, {valueParameter, streamParameter})
Dim retDeletage = retLambda.Compile()
Return retDeletage
End Function
当我为给定的运行时事件类型它创建一个羊羔da表达式如下: -
When I run this for a given event type it creates a lambda expression like:-
.Block(
CQRSAzure.EventSourcing.UnitTest.Mocking.MockEventTypeTwo $eventToSerialise,
System.IO.Stream $stream) {
.Block(
CQRSAzure.EventSourcing.UnitTest.Mocking.MockEventTypeTwo $eventToSerialise,
System.IO.Stream $stream,
System.Int64 $sequence,
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter $bf) {
$sequence = .New System.Int64();
$bf = .New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
.Call $bf.Serialize(
$stream,
$eventToSerialise);
$sequence = $stream.Position;
$sequence
}
}
当我调用这个Lambda函数时,它会返回流位置(在变量sequence中),但是流本身不会写回我传入的变量。
我尝试了什么:
尝试改变方法签名
When I call this Lambda function it does return the stream position (in the variable "sequence") but the stream itself is not written back to the variable I pass in.
What I have tried:
Tried changing around the method signature
{Method = {Int64 lambda_method(System.Runtime.CompilerServices.Closure, CQRSAzure.EventSourcing.UnitTest.Mocking.MockEventTypeTwo, System.IO.Stream)}}
这表示正在传入流 - 并且长度也在设置中。?
This shows the stream is being passed in - and the length is also being set..?
推荐答案
eventToSerialise,
System.IO。 Stream
eventToSerialise, System.IO.Stream
stream){
.Block(
CQRSAzure.EventSourcing.UnitTest.Mocking.MockEventTypeTwo
stream) { .Block( CQRSAzure.EventSourcing.UnitTest.Mocking.MockEventTypeTwo
eventToSerialise,
System.IO.Stream
eventToSerialise, System.IO.Stream
这篇关于通过引用expression.parameter传递system.io.stream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!