Currently I am writing C# code under .NET Core 3.1 for checking if the current type (I use Mono.Cecil
, but System.Reflection
might suit better) is a Span
type. Having found info about how to check if the type is generic, I wrote some dummy code for such sort of check:
unsafe
{
IntPtr unmanagedHandle = Marshal.AllocHGlobal(16);
Span<byte> unmanaged = new Span<byte>(unmanagedHandle.ToPointer(), 16);
if (unmanaged is object)
if ((unmanaged as object).GetType().GetGenericTypeDefinition() == typeof(Span<>))
Console.WriteLine("Span!");
Marshal.FreeHGlobal(unmanagedHandle);
}
Despite the official MSDN docs say that Span<>
IS an object, when compiling, I get stuck with a warning and an error: CS0184 warns that "unmanaged" is never of the "object"
type, and CS0039 tells that "System.Span<byte>" cannot be converted to "object" via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
. At leasts, the docs point out that Span<>
is not a usual object
really.
Is there any other way (having only one dependency Mono.Cecil
) to determine whether some object
(or another underlying piece of data, referred to by the IntPtr
, at least) is a Span-derived?
Well, I know it is not actually fine, but I have to deal with the name checking approach. Due to the semi-object (whatever) nature of the System.Span<T>
class, we cannot compare Span
to any object, but we can use comparation like typeof(System.Span<byte>)
. This can only be useful if we always do know preliminary, how (i.e., with which T
) Span
can be instantiated, but this is NOT my case actually. There seem to be no reliable mechanisms to distinguish Span
, besides name checking. So that, checking the type name seems to be the only suitable approach.
Using Mono.Cecil
, I used for a TypeReference
the following condition:
bool IsSpanType(TypeReference type) {
return type.FullName.StartsWith("System.Span`1");
}
As you see, there is no happy-end, but it works fine enough though. And I cannot see any reasons to perform any more paranoid checks (like checking such properties of TypeReference
like Scope
, ElementType
, or whatever else).