G
Guest
I am desperately trying to build a generic union type with explicit field
layout. First, I will show you my attempt without generics. This is something
like a tagged union in functional languages like F#. Thus let us first write
an example using F#, which is rather short (assuming polymorphic types 'T
stack and 'T queue already defined)
---
type 'T ProcessingOrder = Stack of 'T stack | Queue of 'T queue;;
---
This defines the generic type ProcessingOrder to be either a stack or a
queue, with explicit tags Stack and Queue. 'T is the type parameter. As I
have found out using IL DASM, F# circumvents my problem by using auto layout
and thus does not create a real union type, wasting space.
Let me define the same type using C#:
---
[StructLayout(LayoutKind.Explicit)]
struct ProcessingOrder<T>
{
[FieldOffset(0)] public readonly object _object;
[FieldOffset(0)] public Stack<T> _stack;
[FieldOffset(0)] public Queue<T> _queue;
}
---
Note that I use implicit tagging, as classes in .NET are already tagged. One
may explore the actual type of the union by typeof(_object). Propably not the
fastest way.
Unfortunately, this does not work. Compiles without error messages but at
execution a TypeLoadException is thrown, which tells me that explicit layout
is not allowed for generic types.
Au contraire, a specialized implementation works fine:
---
[StructLayout(LayoutKind.Explicit)]
struct ProcessingOrderInt
{
[FieldOffset(0)] public readonly object _object;
[FieldOffset(0)] public Stack<int> _stack;
[FieldOffset(0)] public Queue<int> _queue;
}
---
Has anyone an idea why explicit layout is forbidden for generic types? Has
anyone an idea how to circumvent this without accouting space for every
choice?
TIA,
Hagen
layout. First, I will show you my attempt without generics. This is something
like a tagged union in functional languages like F#. Thus let us first write
an example using F#, which is rather short (assuming polymorphic types 'T
stack and 'T queue already defined)
---
type 'T ProcessingOrder = Stack of 'T stack | Queue of 'T queue;;
---
This defines the generic type ProcessingOrder to be either a stack or a
queue, with explicit tags Stack and Queue. 'T is the type parameter. As I
have found out using IL DASM, F# circumvents my problem by using auto layout
and thus does not create a real union type, wasting space.
Let me define the same type using C#:
---
[StructLayout(LayoutKind.Explicit)]
struct ProcessingOrder<T>
{
[FieldOffset(0)] public readonly object _object;
[FieldOffset(0)] public Stack<T> _stack;
[FieldOffset(0)] public Queue<T> _queue;
}
---
Note that I use implicit tagging, as classes in .NET are already tagged. One
may explore the actual type of the union by typeof(_object). Propably not the
fastest way.
Unfortunately, this does not work. Compiles without error messages but at
execution a TypeLoadException is thrown, which tells me that explicit layout
is not allowed for generic types.
Au contraire, a specialized implementation works fine:
---
[StructLayout(LayoutKind.Explicit)]
struct ProcessingOrderInt
{
[FieldOffset(0)] public readonly object _object;
[FieldOffset(0)] public Stack<int> _stack;
[FieldOffset(0)] public Queue<int> _queue;
}
---
Has anyone an idea why explicit layout is forbidden for generic types? Has
anyone an idea how to circumvent this without accouting space for every
choice?
TIA,
Hagen