如果一切都失败了,你可以用编译的表达式来做到这一点:
class Program
{
private delegate object ReadDelegate(JsonConverter converter, ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options);
public static void Main()
{
var converter = new FooConverter();
var converterType = converter.GetType();
var typeOfT = typeof(int);
var converterParameter = Expression.Parameter(typeof(JsonConverter));
var readerParameter = Expression.Parameter(typeof(Utf8JsonReader).MakeByRefType());
var typeToConvertParameter = Expression.Parameter(typeof(Type));
var optionsParameter = Expression.Parameter(typeof(JsonSerializerOptions));
var readMethodInfo = converterType.GetMethod("Read");
var castConverter = Expression.Convert(converterParameter, converterType);
var call = Expression.Call(
castConverter,
readMethodInfo,
readerParameter,
typeToConvertParameter,
optionsParameter);
var castResult = Expression.Convert(call, typeof(object));
var lambda = Expression.Lambda<ReadDelegate>(
castResult,
converterParameter,
readerParameter,
typeToConvertParameter,
optionsParameter).Compile();
var reader = new Utf8JsonReader();
var result = lambda(converter, ref reader, typeof(int), new JsonSerializerOptions());
}
}
public class FooConverter : JsonConverter<int>
{
public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => 3;
public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) => throw new NotImplementedException();
}
确保您缓存了lambda——创建它的成本相对较高,但调用起来却非常便宜。
这实质上是在运行时构建一个方法,看起来有点像这样:
public object Lambda(
JsonConverter converterParameter,
ref Utf8JsonReader readerParameter,
Type typeToConvertParameter,
JsonSerializerOptions optionsParameter)
{
var castConverter = (FooConverter)converterParameter;
var call = castConverter.Read(ref readerParameter, typeToConvertParameter, optionsParameter);
return (object)call;
}
也就是说,您最好编写一个泛型方法,然后使用反射调用它,而不是使用反射直接调用Read 方法:
class Program
{
public static void Main()
{
var converter = new FooConverter();
var typeOfT = typeof(int);
var methodInfo = typeof(Program).GetMethod("Foo").MakeGenericMethod(typeOfT);
var result = methodInfo.Invoke(null, new[] { converter });
}
public static T Foo<T>(JsonConverter<T> converter)
{
var reader = new Utf8JsonReader();
return converter.Read(ref reader, typeof(int), new JsonSerializerOptions());
}
}
诚然,这确实只是解决了问题,但它可能对你有用。