У этого класса нет общедоступного конструктора, но его можно создать с помощью статический метод Create
public static IPagedList Create(IEnumerable items, int pageNumber, int pageSize, int totalItems) {
Ensure.That.IsNotNull(items);
Ensure.That.IsNotZeroOrNegative(pageNumber);
Ensure.That.IsNotZeroOrNegative(pageSize);
var totalItemCount = totalItems;
return new PagedList(items, pageNumber, pageSize, totalItemCount);
}
Этот метод просто вызывает конструктор, который объявлен как частный защищенный.
Если метод Create вызывается напрямую, возвращаемый объект — это IPagedList
Однако, когда метод вызывается посредством отражения, возвращаемым типом является PagedListЭто код для размышления
var typeToCall = typeof(PagedList).MakeGenericType(targetType);
MethodInfo createMethod = typeToCall.GetMethod("Create")!;
dynamic result = createMethod.Invoke(null, new object[] { value, pageNumber, pageSize, totalItems })!;
return (IPagedList)result!;

Есть такое поведение нормальное? Это происходит из-за того, что я использую динамический?
Когда созданный объект возвращается вызывающей стороне, которая ожидает IPagedList, я получаю исключение, которое говорит
System.InvalidCastException: невозможно привести объект типа «ApiResult»1[PagedList1[ProgramResponse]]', чтобы ввести 'ApiResult1[IPagedList1[ProgramResponse]]'.
at System.Text.Json.ThrowHelper.ThrowInvalidCastException_DeserializeUnableToAssignValue(Type typeOfValue, Type declaredType)
at System.Text.Json.JsonSerializer.g__ThrowUnableToCastValue|50_0[T](Object value)
at System.Text.Json.JsonSerializer.UnboxOnRead[T](Object value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
Я включаю полную версию JsonConverter, которая десериализует объект IPagedList
internal class NativePagedListConverter : JsonConverter {
public override bool CanConvert(Type typeToConvert) {
return typeToConvert.IsPagedList();
}
public override IPagedList? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
if (reader.TokenType != JsonTokenType.StartObject) {
throw new JsonException();
}
int pageNumber = 0;
int pageSize = 0;
int totalItems = 0;
dynamic value = default!;
var targetType = typeToConvert.GetGenericArguments()[0]!;
while (reader.Read()) {
if (reader.TokenType == JsonTokenType.EndObject) {
break;
}
if (reader.TokenType != JsonTokenType.PropertyName) {
throw new JsonException();
}
var propertyName = reader.GetString() ?? string.Empty;
reader.Read();
if (propertyName.Equals(nameof(pageNumber), StringComparison.OrdinalIgnoreCase)) {
pageNumber = reader.GetInt32();
}
else if (propertyName.Equals(nameof(pageSize), StringComparison.OrdinalIgnoreCase)) {
pageSize = reader.GetInt32();
}
else if (propertyName.Equals(nameof(totalItems), StringComparison.OrdinalIgnoreCase)) {
totalItems = reader.GetInt32();
}
else if (propertyName.Equals("Items", StringComparison.OrdinalIgnoreCase)) {
var itemsType = typeof(IEnumerable).MakeGenericType(targetType);
value = JsonSerializer.Deserialize(ref reader, itemsType, options)!;
}
}
var typeToCall = typeof(PagedList).MakeGenericType(targetType);
MethodInfo createMethod = typeToCall.GetMethod("Create")!;
dynamic result = createMethod.Invoke(null, new object[] { value, pageNumber, pageSize, totalItems })!;
return (IPagedList)result!;
}
public override void Write(Utf8JsonWriter writer, IPagedList value, JsonSerializerOptions options) {
[...omitted as not interesting for the question...]
}
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... h-reflecti
Мобильная версия