我正在尝试为一个已经存在的对象调用反序列化构造函数。我如何使用表达式树来做到这一点?
我试过:
// Create an uninitialized object
T graph = (T)FormatterServices.GetUninitializedObject(graphType);
// (graph, serializationInfo, streamingContext) => graph.Constructor(serializationInfo, streamingContext)
ParameterExpression graphParameter = Expression.Parameter(serializationPack.SelfSerializingBaseClassType, "graph");
ParameterExpression serializationInfoParameter = Expression.Parameter(typeof(SerializationInfo), "serializationInfo");
ParameterExpression streamingContextParameter = Expression.Parameter(typeof(StreamingContext), "streamingContext");
MethodCallExpression callDeserializationConstructor = Expression.Call(graphParameter,
(MethodInfo)serializationPack.SelfSerializingBaseClassType.GetConstructor(new[] { typeof(SerializationInfo), typeof(StreamingContext) }),
new[] { serializationInfoParameter, streamingContextParameter });
但是 Expression.Call
只接受 MethodInfo
而不是 ConstructorInfo
,所以这不起作用 - 除非有一种方法可以转换为方法信息
?
更新
我只使用了 ConstructorInfo.Invoke
:
// Cache this part
ConstructorInfo deserializationConstructor = serializationPack
.SelfSerializingBaseClassType
.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard,
new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
// Call this when I need it
deserializationConstructor.Invoke(graph, new Object[] { serializationInfo, new StreamingContext() });
我害怕它的性能,但这似乎是唯一的方法。
更新
现在有了正确的答案。谢谢大家。
最佳答案
如果你想使用表达式树,使用Expression.New .这是一个例子
var info = Expression.Parameter(typeof(SerializationInfo), "info");
var context = Expression.Parameter(typeof(StreamingContext), "context");
var callTheCtor = Expression.New(ctorInfo, info, context);
这不适用于现有对象,但由于您的代码显示了 GetUninitializedObject
我认为您可以删除该部分并使用 Expression.New
创建一个新对象。
关于c# - 如何通过现有对象上的表达式树调用构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16363838/