Возвращаемый объект не является тем, который объявлен по сигнатуре при вызове посредством отражения.C#

Место общения программистов C#
Ответить
Anonymous
 Возвращаемый объект не является тем, который объявлен по сигнатуре при вызове посредством отражения.

Сообщение Anonymous »

У меня есть класс PagedList, который реализует интерфейс IPagedList
У этого класса нет общедоступного конструктора, но его можно создать с помощью статический метод 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»