我知道this问题,这是后续问题,也是this问题,但我不能将它们放在一起,以帮助我做我想做的事情做:
我有一个泛型类型,我想检查T是struct
OR如果它实现IEnumerable<T2>
,那么我想检查T2是struct
。
到目前为止,我已经到了这里('请原谅代码,这是实验性的):
private class TestClass<T>
{
public TestClass()
{
Type type = typeof(T);
//(detecting T == IEnumerable<something> ommitted for clarity)
Type enumerableType = type.GetInterfaces()
.Where(t => t.IsGenericType)
.Select(t => t.GetGenericTypeDefinition())
.Where(t => t == typeof(IEnumerable<>))
.FirstOrDefault();
if(enumerableType != null)
{
Type enumeratedType = type.GetGenericArguments().First();
if(!enumeratedType.IsValueType) //throw etc...
}
}
}
我遇到的问题是enumerableType
为IEnumerable<>
,因此enumeratedType
出现为T
,而不是我传入的任何内容(例如new TestClass<int[]>()
}})。
答案 0 :(得分:4)
您的问题是您选择了包含所有数据的类型,而不是使用已删除的通用类型模板。
尝试:
Type enumerableType = type.GetInterfaces()
.Where(t => t.IsGenericType)
.Where(t => t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
.Select(t => t.GetGenericArguments()[0])
.FirstOrDefault();
答案 1 :(得分:2)
internal static class TypeSystem {
internal static Type GetElementType(Type seqType) {
Type ienum = FindIEnumerable(seqType);
if (ienum == null) return seqType;
return ienum.GetGenericArguments()[0];
}
private static Type FindIEnumerable(Type seqType) {
if (seqType == null || seqType == typeof(string))
return null;
if (seqType.IsArray)
return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType());
if (seqType.IsGenericType) {
foreach (Type arg in seqType.GetGenericArguments()) {
Type ienum = typeof(IEnumerable<>).MakeGenericType(arg);
if (ienum.IsAssignableFrom(seqType)) {
return ienum;
}
}
}
Type[] ifaces = seqType.GetInterfaces();
if (ifaces != null && ifaces.Length > 0) {
foreach (Type iface in ifaces) {
Type ienum = FindIEnumerable(iface);
if (ienum != null) return ienum;
}
}
if (seqType.BaseType != null && seqType.BaseType != typeof(object)) {
return FindIEnumerable(seqType.BaseType);
}
return null;
}
}
答案 2 :(得分:0)
我相信这段代码可以满足您的需求。
public class TestClass<T>
{
public TestClass()
{
bool hasStruct = false;
Type t1 = this.GetType().GetGenericArguments()[0];
if(t1.IsValueType){
hasStruct = true;
}
if (t1.IsGenericType)
{
Type t = t1.GetGenericArguments()[0];
if (t.IsValueType)
{
hasStruct = true;
}
}
}
}