Reputation: 9285
I have two parameters I receive using reflection that could be of different types.
object array;
object value;
...
array=new int[] { 1,2,3};
value=3;
...
array=new string[] { "one","two","three"};
value="two";
I want to find out if value
is inside array
, no matter which type.
The following command does not compile:
bool isInside=Array.Exists(array, q=>q==value);
The type arguments for method 'Array.Exists(T[], Predicate)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
How can I achieve my goal?
Upvotes: 2
Views: 1149
Reputation: 344
Obligatory answer using 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;
}
EDIT: Looking ot other solutions, I wouldn't really recommand this one, as reflection is slow and others did it far more elegantly.
Upvotes: 0
Reputation: 1440
Please try this one
var dynamicArray = (object[])array;
bool isInside = dynamicArray.Contains(value);
Upvotes: -1
Reputation: 825
OS it is still an Array. So lets start with defining the variables as
Array array;
object value;
Array is IEnumerable we can define an extension class:
public static class EnumerableExtensions
{
public static bool HasItem(this IEnumerable enumerable, object value)
{
return enumerable.OfType<Object>().Any(e => e.Equals(value));
}
}
and use it like this:
Array array = new[] { 1, 2, 3 };
object value = 1;
//false because the value is a string.
var result = array.HasItem("1");
if you need it to be true some convertion logic should be added to HasItem method
Upvotes: 1
Reputation: 270860
One way I can think of is to cast the array to Array
, then use a for loop to search through it:
var castedArray = (Array)array;
for (int i = 0 ; i < castedArray.Length ; i++) {
if (castedArray.GetValue(i).Equals(value)) {
Console.WriteLine("It exists!");
break;
}
}
Note that ==
won't work here because int
s will be boxed.
If your arrays only have one dimension, Array.IndexOf
would work as well (with castedArray
and value
), but if you want to handle 2D or 3D arrays as well, you need to check the Rank
and use nested for loops.
Upvotes: 3