Есть ли способ получить свойство ref struct с помощью отражения?C#

Место общения программистов C#
Ответить
Anonymous
 Есть ли способ получить свойство ref struct с помощью отражения?

Сообщение Anonymous »

Давайте воспользуемся System.Text.RegularExpressions.Match в качестве примера. Он имеет член структуры ref ReadOnlySpan ValueSpan.
Использование отражения обычным способом не будет работать, поскольку члены структуры ref не могут быть упакованы (превращены в System.Object).

Код: Выделить всё

Match match = new Regex("\\d+").Match("testing 123"); // Create test data
PropertyInfo[] props = match.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
var values = props.Select(s => (s.Name, s.GetValue(match, null))).ToArray();
Если вы попытаетесь запустить приведенный выше код, программа завершится с System.NotSupportedException. Когда PropertyInfo.GetValue(object? obj, object?[]? index) вызывается с PropertyInfo для Match.ValueSpan, срабатывает исключение.
Я пытаюсь создать инспектор объектов, который может просматривать поля и свойства объектов. В идеале должен быть способ вызвать метод, который принимает проверяемый объект (в нашем случае Match), имя строкового свойства (в нашем случае "ValueSpan") и тип возвращаемого значения (в нашем случае typeof(ReadOnlySpan)).
Что-то вроде этого:

Код: Выделить всё

Match match = new Regex("\\d+").Match("testing 123"); // Create test data
var result = GetProperty(match, "ValueSpan", typeof(ReadOnlySpan))
Однако возникает проблема: к какому типу будет относиться результат var? Это не может быть объект, поскольку match.ValueSpan является ссылочной структурой. Есть ли какое-нибудь решение этой проблемы?
Я уже пытался решить эту проблему разными способами, наиболее многообещающим из которых было использование деревьев выражений. Следующий метод принимает проверяемый объект и имя свойства в качестве параметров, но требует знания типа возвращаемого значения:

Код: Выделить всё

public static T GetProperty(object target, string name) where T : allows ref struct
{
var arg = Expression.Parameter(typeof(object));
var expr = Expression.Property(Expression.Convert(arg, target.GetType()), name);
var compiled = Expression.Lambda(expr, arg).Compile();
return compiled(target);
}
Тогда это можно назвать так:

Код: Выделить всё

Match match = new Regex("\\d+").Match("testing 123"); // Create test data
var result = GetProperty(match, "ValueSpan")
Для дальнейшего решения я бы хотел иметь возможность объявлять тип возвращаемого значения как параметр функции (вместо общего параметра).
Даже хакерские способы приветствуются. Я думал о чем-то вроде создания поддельной структуры «базового типа» и копирования данных с помощью указателей, включая RuntimeHandle. Некоторые сведения о том, как нам нужно создать тип, который может быть заменителем любого типа, включая ссылочные структуры. Мысли по этому поводу?

Подробнее здесь: https://stackoverflow.com/questions/799 ... reflection
Ответить

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

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

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

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

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