Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9162269
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T14:10:13+00:00 2026-06-17T14:10:13+00:00

Is there a way to mark a type (or even better, an interface) so

  • 0
  • 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 and ArgIterator)?
  • 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;
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-17T14:10:14+00:00Added an answer on June 17, 2026 at 2:10 pm

    Okay. This isn’t quite a complete analysis, but I suspect it’s a sufficient one for the purposes of determining whether you can do this, even by twiddling IL – which, so far as I can tell, you can’t.

    I also, on looking at the decompiled version with dotPeek, couldn’t see anything special about that particular type/those particular types in there, attribute-wise or otherwise:

    namespace System
    {
      /// <summary>
      /// Describes objects that contain both a managed pointer to a location and a runtime representation of the type that may be stored at that location.
      /// </summary>
      /// <filterpriority>2</filterpriority>
      [ComVisible(true)]
      [CLSCompliant(false)]
      public struct TypedReference
      {
    

    So, that done, I tried creating such a class using System.Reflection.Emit:

    namespace NonStorableTest
    {
        //public class Invalid
        //{
        //    public TypedReference i;
        //}
    
        class Program
        {
            static void Main(string[] args)
            {
                AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("EmitNonStorable"),
                                                                                           AssemblyBuilderAccess.RunAndSave);
    
                ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule("EmitNonStorable", "EmitNonStorable.dll");
    
                TypeBuilder invalidBuilder = moduleBuilder.DefineType("EmitNonStorable.Invalid",
                                                                      TypeAttributes.Class | TypeAttributes.Public);
    
                ConstructorBuilder constructorBuilder = invalidBuilder.DefineDefaultConstructor(MethodAttributes.Public);
    
                FieldBuilder fieldI = invalidBuilder.DefineField("i", typeof (TypedReference), FieldAttributes.Public);
    
                invalidBuilder.CreateType();
                asmBuilder.Save("EmitNonStorable.dll");
    
                Console.ReadLine();
            }
        }
    }
    

    That, when you run it, throws a TypeLoadException, the stack trace of which points you to System.Reflection.Emit.TypeBuilder.TermCreateClass. So then I went after that with the decompiler, which gave me this:

    [SuppressUnmanagedCodeSecurity]
    [SecurityCritical]
    [DllImport("QCall", CharSet = CharSet.Unicode)]
    private static void TermCreateClass(RuntimeModule module, int tk, ObjectHandleOnStack type);
    

    Pointing into the unmanaged parts of the CLR. At this point, not to be defeated, I dug into the shared sources for the reference version of the CLR. I won’t go through all the tracing through that I did, to avoid bloating this answer beyond all reasonable use, but eventually, you end up in \clr\src\vm\class.cpp, in the MethodTableBuilder::SetupMethodTable2 function (which also appears to set up field descriptors), where you find these lines:

    // Mark the special types that have embeded stack poitners in them
                            if (strcmp(name, "ArgIterator") == 0 || strcmp(name, "RuntimeArgumentHandle") == 0)
                                pClass->SetContainsStackPtr();
    

    and

    if (pMT->GetInternalCorElementType() == ELEMENT_TYPE_TYPEDBYREF)
                                pClass->SetContainsStackPtr();
    

    This latter relating to information found in \src\inc\cortypeinfo.h, thus:

    // This describes information about the COM+ primitive types
    
    // TYPEINFO(enumName,               className,          size,           gcType,         isArray,isPrim, isFloat,isModifier)
    
    [...]
    
    TYPEINFO(ELEMENT_TYPE_TYPEDBYREF,  "System", "TypedReference",2*sizeof(void*), TYPE_GC_BYREF, false,  false,  false,  false)
    

    (It’s actually the only ELEMENT_TYPE_TYPEDBYREF type in that list.)

    ContainsStackPtr() is then in turn used elsewhere in various places to prevent those particular types from being used, including in fields – from \src\vm\class.cp, MethodTableBuilder::InitializeFieldDescs():

    // If it is an illegal type, say so
    if (pByValueClass->ContainsStackPtr())
    {
        BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT, IDS_CLASSLOAD_BAD_FIELD, mdTokenNil);
    }
    

    Anyway: to cut a long, long, long story short, it would seem to be the case that which types are non-storable in this way is effectively hard-coded into the CLR, and thus that if you want to change the list or provide an IL means to flag up types as non-storable, you’re pretty much going to have to take Mono or the shared-source CLR and spin off your own version.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Is there a way to mark a string such that it will not trigger
Is there a way to mark an auto-generated class as ExcludeFromCodeCoverage. I am using
Is there a way to mark issues with different options than the default Bug\Feature\Support
Is there a way to somehow mark Types I do not control as Obsolete?
Is there way to better identify design pattern in source codes, esp. if you
Is there a somewhat standardized way to semantically mark up citations in HTML? I
Is there way to get file from windows xp command prompt? I tried to
Is there way to automatically maximize the output window on hitting build and then
Is there way to copy a file into Plone with WebDAV and have Plone
is there way how to get name ov event from Lambda expression like with

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.