C# 检查任何类型的数组是否包含元素
我有两个使用反射接收的参数,它们可能是不同类型的C# 检查任何类型的数组是否包含元素,c#,arrays,C#,Arrays,我有两个使用反射接收的参数,它们可能是不同类型的 object array; object value; 我想知道值是否在数组中,无论是哪种类型。 以下命令不编译: 无法从用法推断方法“Array.Exists(T[],谓词)”的类型参数。尝试显式指定类型参数 如何实现我的目标?我可以想到的一种方法是将数组强制转换为数组,然后使用for循环在其中搜索: var castedArray = (Array)array; for (int i = 0 ; i < castedArray.L
object array;
object value;
我想知道值
是否在数组
中,无论是哪种类型。
以下命令不编译:
无法从用法推断方法“Array.Exists(T[],谓词)”的类型参数。尝试显式指定类型参数
如何实现我的目标?我可以想到的一种方法是将数组强制转换为
数组,然后使用for循环在其中搜索:
var castedArray = (Array)array;
for (int i = 0 ; i < castedArray.Length ; i++) {
if (castedArray.GetValue(i).Equals(value)) {
Console.WriteLine("It exists!");
break;
}
}
var castedArray=(数组)数组;
for(int i=0;i
请注意,=
在这里不起作用,因为int
s将被装箱
如果您的数组只有一个维度,Array.IndexOf
也可以工作(使用castedArray
和value
),但是如果您想处理二维或三维数组,则需要检查秩
并使用嵌套for循环。操作系统它仍然是一个数组。因此,让我们首先将变量定义为
Array array;
object value;
数组是IEnumerable我们可以定义一个扩展类:
public static class EnumerableExtensions
{
public static bool HasItem(this IEnumerable enumerable, object value)
{
return enumerable.OfType<Object>().Any(e => e.Equals(value));
}
}
如果您需要它为真,则应将一些转换逻辑添加到HasItem方法中请尝试此方法
var dynamicArray = (object[])array;
bool isInside = dynamicArray.Contains(value);
使用LINQ的强制回答:
//using System.Linq;
//using System.Reflection;
public static bool IsInArrayUnkownType(object array, object obj)
{
Type type = array.GetType().GetElementType();
MethodInfo contains = typeof(System.Linq.Enumerable).GetMethods().Where(m => m.Name == "Contains").First();
MethodInfo containsUnGenericated = contains.MakeGenericMethod(new[] { type });
object result = containsUnGenericated.Invoke(null, new object[] { array, obj });
return (bool)result;
}
编辑:从其他解决方案来看,我并不推荐使用此解决方案,因为反射速度慢,而其他解决方案则要优雅得多。为什么要首先在对象中存储数组?使用真实类型,所有这些都会消失。或者更好的方法是,使用类似于List
Array的方法。IndexOf((Array)Array,)>=0
应该可以工作,而不管数组类型和项值如何。但这并不是你所说的优雅或高效。(对于非0界的数组,您需要更加小心,但这些数组的存在在C#中大多被忽略。)您希望如何将int[]
强制转换为object[]
?是的,反射是解决此问题的一种糟糕方法,为什么您甚至会建议它?@DavidG老实说,主要是想看看是否可以这样做。
public static class EnumerableExtensions
{
public static bool HasItem(this IEnumerable enumerable, object value)
{
return enumerable.OfType<Object>().Any(e => e.Equals(value));
}
}
Array array = new[] { 1, 2, 3 };
object value = 1;
//false because the value is a string.
var result = array.HasItem("1");
var dynamicArray = (object[])array;
bool isInside = dynamicArray.Contains(value);
//using System.Linq;
//using System.Reflection;
public static bool IsInArrayUnkownType(object array, object obj)
{
Type type = array.GetType().GetElementType();
MethodInfo contains = typeof(System.Linq.Enumerable).GetMethods().Where(m => m.Name == "Contains").First();
MethodInfo containsUnGenericated = contains.MakeGenericMethod(new[] { type });
object result = containsUnGenericated.Invoke(null, new object[] { array, obj });
return (bool)result;
}