Tim*_*lds 5 .net c# generics system.reflection
我使用的是C#/ .NET 4.0和一个Protocol Buffers库(protobuf-net),它提供了以下功能.
public static class Serializer {
public static void Serialize<T>(Stream destination, T instance);
public static void Serialize<T>(SerializationInfo info, T instance);
public static void Serialize<T>(XmlWriter writer, T instance);
public static void Serialize<T>(SerializationInfo info, StreamingContext context, T instance);
public static T Deserialize<T>(Stream source);
}
Run Code Online (Sandbox Code Playgroud)
我需要使用非泛型等价物包装其中两个调用.具体来说,我想要
void SerializeReflection(Stream destination, object instance);
object DeserializeReflection(Stream source, Type type);
Run Code Online (Sandbox Code Playgroud)
它只是Serializer在运行时调用相应的通用成员.我已经得到了DeserializeReflection使用以下代码的方法:
public static object DeserializeReflection(Stream stream, Type type)
{
return typeof(Serializer)
.GetMethod("Deserialize")
.MakeGenericMethod(type)
.Invoke(null, new object[] { stream });
}
Run Code Online (Sandbox Code Playgroud)
这种SerializeReflection方法给我带来了麻烦.我刚开始尝试以下代码:
public static void SerializeReflection(Stream stream, object instance)
{
typeof(Serializer)
.GetMethod("Serialize")
.MakeGenericMethod(instance.GetType())
.Invoke(null, new object[] { stream, instance });
}
Run Code Online (Sandbox Code Playgroud)
问题是,之间的部分typeof(Serializer)和.Invoke(...)不工作.调用GetMethod("Serialize")让我一个AmbiguousMatchException,因为有四个方法名为" Serialize."
然后我尝试使用重载GetMethod来获取System.Type解决绑定的数组:
GetMethod("Serialize", new[] { typeof(Stream), instance.GetType() })
Run Code Online (Sandbox Code Playgroud)
但这只是结果GetMethod null.
如何使用反射来获取MethodInfo的void Serializer.Serialize<T>(Stream, T),在那里T是instance.GetType()?
尝试使用下一个代码片段看看它是否满足您的需求。它创建 method 的封闭类型实例public static void Serialize<T>(Stream destination, T instance)。在本例中,它选择第一个方法作为Stream参数,但您可以将此谓词更改method.GetParameters().Any(par => par.ParameterType == typeof(Stream))为您想要的任何内容
public static object DeserializeReflection(Stream stream, object instance)
{
return typeof(Serializer)
.GetMethods()
.First(method => method.Name == "Serialize" && method.GetParameters().Any(par => par.ParameterType == typeof(Stream)))
.MakeGenericMethod(instance.GetType())
.Invoke(null, new object[] { stream, instance });
}
Run Code Online (Sandbox Code Playgroud)