我有一个用例,需要检查一个值是否是C 7值元组,如果是,则循环遍历每个项。我试着用obj is ValueTuple
和obj is (object, object)
检查,但都返回false。我发现我可以使用obj.GetType().Name
并检查它是否以"ValueTuple"
开头,但这对我来说似乎很糟糕。任何其他选择都将受到欢迎。
我还有一个问题就是要买每一件东西。我试图用这里找到的解决方案获取Item1
,但((dynamic)obj).GetType().GetProperty("Item1")
返回空值。我希望我能做一个while
来获得每一个项目。但这不管用。我怎样才能得到每一个项目?
更新-更多代码
if (item is ValueTuple) //this does not work, but I can do a GetType and check the name
{
object tupleValue;
int nth = 1;
while ((tupleValue = ((dynamic)item).GetType().GetProperty($"Item{nth}")) != null && //this does not work
nth <= 8)
{
nth++;
//Do stuff
}
}
最佳答案
结构在c_中不继承,因此ValueTuple<T1>
、ValueTuple<T1,T2>
、ValueTuple<T1,T2,T3>
等是不同的类型,它们不从ValueTuple
继承为基。因此,obj is ValueTuple
检查失败。
如果您正在寻找具有任意类型参数的ValueTuple
,您可以检查该类是否为“cc>”:
private static readonly Set<Type> ValTupleTypes = new HashSet<Type>(
new Type[] { typeof(ValueTuple<>), typeof(ValueTuple<,>),
typeof(ValueTuple<,,>), typeof(ValueTuple<,,,>),
typeof(ValueTuple<,,,,>), typeof(ValueTuple<,,,,,>),
typeof(ValueTuple<,,,,,,>), typeof(ValueTuple<,,,,,,,>)
}
);
static bool IsValueTuple2(object obj) {
var type = obj.GetType();
return type.IsGenericType
&& ValTupleTypes.Contains(type.GetGenericTypeDefinition());
}
要根据类型获取子项,可以使用不是特别快的方法,但应该做到以下几点:
static readonly IDictionary<Type,Func<object,object[]>> GetItems = new Dictonary<Type,Func<object,object[]>> {
[typeof(ValueTuple<>)] = o => new object[] {((dynamic)o).Item1}
, [typeof(ValueTuple<,>)] = o => new object[] {((dynamic)o).Item1, ((dynamic)o).Item2}
, [typeof(ValueTuple<,,>)] = o => new object[] {((dynamic)o).Item1, ((dynamic)o).Item2, ((dynamic)o).Item3}
, ...
};
这样你就可以做到:
object[] items = null;
var type = obj.GetType();
if (type.IsGeneric && GetItems.TryGetValue(type.GetGenericTypeDefinition(), out var itemGetter)) {
items = itemGetter(obj);
}