- Is there a way to mark a type (or even better, an interface) so that no instances of it can be stored in a field (in a similar way to
TypedReference
andArgIterator
)? - In the same way, is there a way to prevent instances from being passed through anonymous methods and -- In general -- To mimic the behavior of the two types above?
- Can this be done through ILDasm or more generally through IL editing? Since UnconstrainedMelody achieves normally unobtainable results through binary editing of a compiled assembly, maybe there's a way to "mark" certain types (or even better, abstract ones or marker interfaces) through the same approach.
I doubt it’s hardcoded in the compiler because the documentation for the error CS0610 states:
There are some types that cannot be used as fields or properties. These types include...
Which in my opinion hints that the set of types like those can be extended -- But I could be wrong.
I've searched a bit on SO and while I understand that throwing a compiler error programmatically can't be done, I could find no source stating that certain "special" types' behaviors couldn't be replicated.
Even if the question is mostly academic, there could be some usages for an answer. For example, it could be useful sometimes to be sure that a certain object's lifetime is constrained to the method block which creates it.
EDIT: RuntimeArgumentHandle
is one more (unmentioned) non-storable type.
EDIT 2: If it can be of any use, it seems that the CLR treats those types in a different way as well, if not only the compiler (still assuming that the types are in no way different from others). The following program, for example, will throw a TypeLoadException
regarding TypedReference*
. I've adapted it to make it shorter but you can work around it all you want. Changing the pointer's type to, say, void*
will not throw the exception.
using System;
unsafe static class Program
{
static TypedReference* _tr;
static void Main(string[] args)
{
_tr = (TypedReference*) IntPtr.Zero;
}
}