我正在尝试进行一个简单的测试,在其中我将两个通用对象传递给测试函数,看看它们是否可以转换为List<S>
,并进一步检查列表的计数是否相等
以下代码有效:
private static void Test<T> (T obj1, T obj2) {
if (typeof(T).IsGenericType) {
var genericTypeParam1 = typeof(T).GetGenericArguments().First();
Console.WriteLine(genericTypeParam1);
// LINE MARKER 1
// var obj1AsList = (obj1 as IEnumerable<genericTypeParam1>);
}
}
static void Main(string[] args) {
Test(Enumerable.Range(0, 5).ToList(), Enumerable.Range(0, 5).ToList());
Console.ReadLine();
}
但如果我取消注释标有LINE MARKER 1
的行,我会收到以下错误:
The type or namespace name 'genericTypeParam1' could not be found (are you missing a using directive or an assembly reference?)
我事先不知道Test会收到List
。但我的目的是首先检查obj1
和obj2
是否可以作为列表,然后进行比较
var obj1AsList = obj1 as List<genericTypeParam1>;
var obj2AsList = obj2 as List<genericTypeParam1>;
var flag = (obj1AsList != null) && (obj2AsList != null) && (obj1AsList.Count() == obj2AsList.Count());
提前感谢您的帮助。
答案 0 :(得分:4)
我正在尝试进行一个简单的测试,其中我将两个对象传递给测试函数,看看它们是否可以转换为
List<S>
,并进一步检查列表的计数是否相等。
正确的方法是:
static bool Test<T>(object obj1, object obj2)
{
List<T> list1 = obj1 as List<T>;
List<T> list2 = obj2 as List<T>;
return list1 != null && list2 != null && list1.Count == list2.Count;
}
...
bool result = Test<int>(Enumerable.Range(0, 5).ToList(), Enumerable.Range(0, 5).ToList());
这需要两个对象和一个类型,如果对象是该类型的大小相同的列表,则返回true。
答案 1 :(得分:2)
作为泛型类型参数提供的类型必须在编译时知道。你试图传递Type
类型的变量,这就是你得到编译类型错误的原因。
您可以证明,在编译期间,编译器只能传递List<T>
个实例作为方法参数进行检查:
private static void Test<T>(List<T> obj1, List<T> obj2)
{
var flag = obj1 != null && obj2 != null && obj1.Count == obj2.Count;
}
如果您希望在运行期间完成该测试,则应使用Eric提供的解决方案。
答案 2 :(得分:1)
如果真正的目标是确保两个项都可以转换为某种通用列表类型,那么只需将对象转换为非通用IList
接口。然后你可以比较计数:
private static bool Test<T>(T obj1, T obj2)
{
if (typeof(T).IsGenericType)
{
var obj1List = obj1 as System.Collections.IList;
var obj2List = obj2 as System.Collections.IList;
if (obj1List != null && obj2List != null && obj1List.Count == obj2List.Count)
return true;
}
return false;
}
如果你真的想使用反射,你可能会做出像这样的工作:
if (typeof(T).IsGenericType) {
var genericTypeParam1 = typeof(T).GetGenericArguments().First();
Console.WriteLine(genericTypeParam1);
// LINE MARKER 1
// var obj1AsList = (obj1 as IEnumerable<genericTypeParam1>);
var genericListType = typeof(IEnumerable<>).MakeGenericType(genericTypeParam1);
Convert.ChangeType(obj1,genericListType);
}