C# 使用反射获取元组的值
所以我尝试使用反射获取元组的值,唯一的问题是我得到了一个异常:System.reflection.TargetInvocationException。我已经试着获得它的价值,正如这里的一条评论所建议的: ,C# 使用反射获取元组的值,c#,reflection,tuples,C#,Reflection,Tuples,所以我尝试使用反射获取元组的值,唯一的问题是我得到了一个异常:System.reflection.TargetInvocationException。我已经试着获得它的价值,正如这里的一条评论所建议的: ,var itemX=t.GetProperty(“itemX”).GetValue(数据)如果我使用lem.FieldType.GetProperty(“Item1”).Name,我可以将名称作为Item1、Item2等返回,我是正确使用它还是有其他方法 FieldInfo[] fields
var itemX=t.GetProperty(“itemX”).GetValue(数据)代码>如果我使用lem.FieldType.GetProperty(“Item1”).Name,我可以将名称作为Item1、Item2等返回,我是正确使用它还是有其他方法
FieldInfo[] fields = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
FieldInfo[] tuples = fields.Where(field=>typeof(IStructuralEquatable).IsAssignableFrom(field.FieldType) && typeof(IStructuralComparable).IsAssignableFrom(field.FieldType)).ToArray();
Debug.WriteLine(tuples.Length.ToString()" ->");
foreach (var elem in tuples)
{
Debug.WriteLine(elem.FieldType.GetProperty("Item1").GetValue(this,null).ToString());
PropertyInfo[] info = elem.FieldType.GetProperties();
Debug.WriteLine(info[0].GetValue(this,null).ToString());
for(int i=0;i<info.Length;i++)
{
Debug.WriteLine(info[i].GetValue(this,null).ToString());
}
FieldInfo[]fields=this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.flatthehierarchy);
FieldInfo[]元组=字段。其中(field=>typeof(IsStructuralEquatable)。IsAssignableFrom(field.FieldType)和&typeof(IsStructuralComparable)。IsAssignableFrom(field.FieldType)).ToArray();
Debug.WriteLine(tuples.Length.ToString()“->”);
foreach(元组中的变量元素)
{
Debug.WriteLine(elem.FieldType.GetProperty(“Item1”).GetValue(this,null.ToString());
PropertyInfo[]info=elem.FieldType.GetProperties();
Debug.WriteLine(信息[0].GetValue(this,null).ToString());
对于(int i=0;i让我们查询其Item1..ItemN
属性的tuple
;我们可以借助Linq和正则表达式,例如
编辑:让我们从获取类型为元组的所有字段开始(请参见下面的注释):
Tuple的定义如下:Tuple
在元组中的值的数量之后,它的逻辑不同
因此,要在所有情况下(即使有8项或更多项)通过反射读取元组,只需使用以下代码(常规编码):
你能发布一个更明确的问题是什么吗?另外,TargetInvocationException包含一个InnerException,这更重要,你能检查它并告诉我们它说了什么吗?tuple.GetType().GetProperties().Where(prop=>Regex.IsMatch(prop.Name,“Item[0-9]+”)。ToDictionary(prop=>prop.Name,prop=>prop.GetValue(tuple));
要获取所有Item1..ItemN
属性名称和值,请小心.ToString()
-如果GetValue(this,null)
返回null
?嘿,谢谢你试图帮助我。我必须更改tupe.GetType()对于tuple.FieldType,但它仍然抛出一个异常:验证System.Text.RegularExpressions.Regex时出错,我添加了tuple的外观like@porsekin:字段信息[]出现问题tuples=fields…
fragment。据我所知,您有一个对象,其中包含类型为Tuple
的字段,您想打印出来。这是您的情况吗?是的,我可以将这些字段放入tuples数组。我想打印出类中每个Tuple的每个值。添加了代码如何获得字段
。如果我删除,在哪里(prop=>Regex.IsMatch(prop.Name,“^Item[0-9]+$”)
,对于value=prop.GetValue(tuple)
@porsekin:获取类型tuple
(以及tuple
,tuple
等)的System.MethodAccessException
)这不是小事;请参阅我的编辑嘿,谢谢。但它是用于ValueTuple扩展的,我不想使用它。如果我尝试将它用于元组,我会得到System.MethodAccessException。
protected Tuple<string,int, int, int> testTuple = new Tuple<string, int, int, int>("Test",1,0,1);
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
...
Dictionary<string, object> result = testTuple
.GetType()
.GetProperties()
.Where(prop => prop.CanRead)
.Where(prop => !prop.GetIndexParameters().Any())
.Where(prop => Regex.IsMatch(prop.Name, "^Item[0-9]+$"))
.ToDictionary(prop => prop.Name, prop => prop.GetValue(testTuple));
...
foreach (var tuple in tuples) {
var result = tuple
.GetType()
.GetProperties()
.Where(prop => prop.CanRead)
.Where(prop => !prop.GetIndexParameters().Any())
.Where(prop => Regex.IsMatch(prop.Name, "^Item[0-9]+$"))
.Select(prop => new {
name = prop.Name,
value = prop.GetValue(tuple),
});
foreach (var item in result)
Debug.WriteLine($"{item.name} = {item.value}");
}
...
Object objectToInspect = this;
HashSet<Type> typleTypes = new HashSet<Type>() {
typeof(Tuple<>),
typeof(Tuple<,>),
typeof(Tuple<,,>),
typeof(Tuple<,,,>),
typeof(Tuple<,,,,>),
typeof(Tuple<,,,,,>),
typeof(Tuple<,,,,,,>),
typeof(Tuple<,,,,,,,>),
};
var fieldsWithTuples = objectToInspect
.GetType()
.GetFields(BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.FlattenHierarchy)
.Where(field => field.FieldType.IsGenericType)
.Where(field => typleTypes.Contains(field.FieldType.GetGenericTypeDefinition()))
.Select(field => new {
name = field.Name,
value = field.GetValue(field.IsStatic
? null // we should provide null for static
: objectToInspect)
})
.Where(item => item.value != null);
// .Select(item => item.value) // if you want tuple values
// .ToArray(); // materialized as an array
foreach (var tuple in fieldsWithTuples.Select(f => f.value)) {
var result = tuple
.GetType()
.GetProperties()
.Where(prop => prop.CanRead)
.Where(prop => !prop.GetIndexParameters().Any())
.Where(prop => Regex.IsMatch(prop.Name, "^Item[0-9]+$"))
.Select(prop => new {
name = prop.Name,
value = prop.GetValue(tuple),
});
foreach (var item in result)
Debug.WriteLine($"{item.name} = {item.value}");
}
public IEnumerable<object> EnumerateValueTuple(object valueTuple)
{
var tuples = new Queue<object>();
tuples.Enqueue(valueTuple);
while (tuples.Count > 0 && tuples.Dequeue() is object tuple)
{
foreach (var field in tuple.GetType().GetFields())
{
if (field.Name == "Rest")
tuples.Enqueue(field.GetValue(tuple));
else
yield return field.GetValue(tuple);
}
}
}
var item = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
foreach(var value in EnumerateValueTuple(item))
Console.Out.WriteLine(value); // Prints "1 2 3 4 5 6 7 8 9 10 11"