【发布时间】:2009-12-11 07:44:23
【问题描述】:
注意,这个问题有点微妙,所以请仔细阅读:我不只是想找出某些 artibitrary 类型是否实现了 IEnumerable:
这是我用初始实现编写的函数:
// is "toType" some sort of sequence that would be satisfied
// by an array of type T? If so, what is the type of T?
// e.g.
// getArrayType(typeof(string[]) == typeof(string)
// getArrayType(typeof(IEnumerable<int>)) == typeof(int)
// getArrayType(typeof(List<string>)) == null // NOTE - Array<string> does not convert to List<string>
// etc.
private static Type getArrayType(Type toType)
{
if (toType.IsArray)
{
if (toType.GetArrayRank() != 1)
return null;
return toType.GetElementType();
}
// Look for IEnumerable<T>, and if so, return the type of T
if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
return toType.GetGenericArguments()[0];
return null;
}
能不能做得更好,处理更多的案件?例如目前
getType(typeof(ICollection<string>)) == null
但 string[] 可以转换为 ICollection
还要注意,我事先并不知道“元素”类型是什么。
上下文是:我正在编写与脚本语言的反射绑定,如果您将 object[] 传递给期望 IEnumerable 的某个方法,我希望它“正常工作”(它将转换输入数组到一个字符串,在这种情况下)。
为了澄清,假设我有一些方法签名:
void WriteCSV(ICollection<string> fields);
我的脚本解释器有一个对象数组,这些对象都恰好可以转换为字符串:
object[] fields = new object[] { "one", 2, "three" };
然后我的脚本解释器需要弄清楚在这种情况下真正需要的是一个字符串数组。
而我希望我的脚本解释器放弃,说:
void WriteCSV(IRecord record);
即使 IRecord 甚至可能实现一些 IEnumerable:
interface IRecord : IEnumerable<string>
{
void OtherMethods();
}
我无法从任何数组中构造一个 IRecord。
所以仅仅找出一个类型实现的 IEnumerables 并不是我所需要的。我说这很微妙不是吗?
【问题讨论】:
-
您能说明一下您的要求是什么吗?你的意图是实现 IEnumerable 的任何东西都应该在这里返回非 null 吗?
-
已澄清。我需要找出可以转换为给定类型的数组类型(如果有的话)。 IEnumerable 是,我认为,我有点红鲱鱼。
-
仅供参考 - 目前您的逻辑仅处理正在传递的数组,因为您永远不会将接口 IEnumerable
传递给方法,只有实现该接口的类。
标签: .net reflection generics