如何检查对象是否是某种类型的数组?

这种方法很有效:

var expectedType = typeof(string);
object value = "...";
if (value.GetType().IsAssignableFrom(expectedType))
{
...
}

但是如何在不将 expectedType设置为 typeof(string[])的情况下检查 value 是否是字符串数组?我想这样做:

var expectedType = typeof(string);
object value = new[] {"...", "---"};
if (value.GetType().IsArrayOf(expectedType)) // <---
{
...
}

这可能吗?

111978 次浏览

Use Type.IsArray and Type.GetElementType() to check the element type of an array.

Type valueType = value.GetType();
if (valueType.IsArray && expectedType.IsAssignableFrom(valueType.GetElementType())
{
...
}

Beware the Type.IsAssignableFrom(). If you want to check the type for an exact match you should check for equality (typeA == typeB). If you want to check if a given type is the type itself or a subclass (or an interface) then you should use Type.IsAssignableFrom():

typeof(BaseClass).IsAssignableFrom(typeof(ExpectedSubclass))

Do you actually need to know the type of the array? Or do you only need the elements to be of a certain type?

If the latter, you can simply filter only the elements that match what you want:

string[] strings = array.OfType<string>();

You can use extension methods (not that you have to but makes it more readable):

public static class TypeExtensions
{
public static bool IsArrayOf<T>(this Type type)
{
return type == typeof (T[]);
}
}

And then use:

Console.WriteLine(new string[0].GetType().IsArrayOf<string>());
value.GetType().GetElementType() == typeof(string)

as an added bonus (but I'm not 100% sure. This is the code I use...)

var ienum = value.GetType().GetInterface("IEnumerable`1");


if (ienum != null) {
var baseTypeForIEnum = ienum.GetGenericArguments()[0]
}

with this you can look for List, IEnumerable... and get the T.

The neatest and securest way to do it that found is using MakeArrayType:

var expectedType = typeof(string);
object value = new[] {"...", "---"};
if (value.GetType() == expectedType.MakeArrayType())
{
...
}
if(objVal.GetType().Name == "Object[]")

true for array

This is another sample,

using System;
using System.Collections.Generic;


public static class Program
{
public static void Main()
{
Type type = typeof(string[]);
// string[], int[], char[], List<MyData>, IList<MyData>, IEnumarable<MyData>  =====> console write "True",
// string, int, MyData etc ==== does not write
        

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>))
{
Type itemType = type.GetGenericArguments()[0];
Console.WriteLine("True");
}


if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
{
Type itemType = type.GetGenericArguments()[0];
Console.WriteLine("True");
}


if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
Type itemType = type.GetGenericArguments()[0];
Console.WriteLine("True");
}
        

if (type.IsArray)
{
Console.WriteLine("True");
}
}
}


public class MyData
{
public string Name { get; set; }
}