Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查任何类型的数组是否包含元素_C#_Arrays - Fatal编程技术网

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;
}