The public of the. Net type is not public, and fixed cannot be fixed.

Source: Internet
Author: User

I have previously written the article "value type is not a value type. Today, another language game: public is not public, and fixed cannot be fixed. This article constructs a weird type: the public field cannot be accessed, but the fixed keyword is marked but cannot be fixed.

(1) Starting with fixed

The typical use of fixed is to obtain the address of the value type or value type array allocated to the managed stack, such:

    public class Test    {        private int Value;        private Int32[] Array = new Int32[3];        public unsafe void Foo()        {            fixed (int* p = &Value)            {                *p = 30;            }            fixed (Int32* pArray = Array)            {                pArray[0] = 30;            }        }    }

Why fixed? If GC exists, the memory occupied by it may be moved at any time. Fixed tells GC that the memory is being operated by the pointer.

Here is another usage of fixed. In C, we can embed arrays in struct, such:

typedef struct S{    int buffer[4];} S;

In C #, if we use the following method, the resulting buffer is actually hosted on the stack, and S itself only stores a reference to the buffer.

struct S{     public int[] buffer = new int[3];}

To create a fixed memory size in the same value type as C, you must use the fixed Keyword:

    unsafe struct S    {        public fixed int buffer[3];    }

The above buffer is a pointer. Assume that the instance S with s is hosted on the stack. When s. buffer is used, s fixed must be set first. If S. buffer is not hosted on the stack, no fixed is required. For details, refer to the Code:

   public unsafe class Example    {        S field = new S();        private bool example1()        {            // ERROR            return field.buffer[2] == 0;        }        private bool example2()        {            // OK            fixed (S* p = &field)            {                return (p->buffer[2] == 0);            }        }        private S example1()        {            // OK            S s = new S();            s.buffer[2] = 0;            return s;        }    }

Unfortunately, the above fixed usage (creating a fixed-size memory within the value type) only supports several basic types: bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float, or double.

What if I want to use another value type?

Through decompilation, we can see that the fixed here is actually a syntactic SUGAR:

Next, we will simulate it and create a memory block of the type not supported by fixed in the value type.

    unsafe struct S2    {        public Block block;        [StructLayout(LayoutKind.Sequential, Size = 24)]        public struct Block        {            public Rgb24 Val0;        }    }    public unsafe class S2Example    {        S2 S = new S2();        private void example1()        {            fixed(S2* p = &S)            {                (&(p->block.Val0))[2].Blue = 25;            }        }    }

(2) Hosting type

Through the study of fixed, I found a very interesting thing. I used to think that as long as it is a value type, you can use a pointer to refer to fixed in the managed heap. This is not the case today. Some value types cannot be indicated by pointers.

What type? Belongs to the managed type value type.

The types in. net can be divided into value type and reference type, or managed type and unmanaged type. What are the differences between the two statements? I will draw a picture to indicate:

The reference type must be a hosted type, but the value type is not necessarily a non-hosted type. Only the unmanaged type can be operated using the unsafe pointer. The hosted type cannot.

What are the managed value types?

Currently, I only found two types:

(1) generic value type!

(2) Fields of a field or field (......) Is managed type!

For example:

    public struct Size<T> where T : struct    {        public T Width;        public T Height;        public Size(T width, T height)        {            Width = width;            Height = height;        }        public static Boolean operator ==(Size<T> lhs, Size<T> rhs)        {            return lhs.Equals(rhs);        }        public static Boolean operator !=(Size<T> lhs, Size<T> rhs)        {            return !lhs.Equals(rhs);        }    }

It is a value type, but it is a type established at runtime. It does not exist during compilation! This type cannot be operated by pointers.

    public unsafe class SizeTExample    {        private void example1()        {            Size<Int32> size = new Size<Int32>();            //Error            Size<Int32>* p = &size;            p->Width = 200;        }    }

(3) Public and fixed are not fixed

With the above discussion, let's construct a strange type:

    unsafe struct S3    {        public Size<Int32> size;        public fixed byte buffer[4];    }

This type has a field size that is a generic value type Size <Int32>. As a result, S3 itself is a value type and also a hosted type. If it is a managed type, pointer operations and other unsafe operations are not allowed. No fixed, no sizeof, and so on. If fixed is not available, the buffer marked as fixed byte cannot be accessed.

    public unsafe class S3Example    {        private void example1()        {            S3 S = new S3();            //Error            fixed (Size<Int32>* p = &size)            {            }        }    }

In this way, we will successfully construct an odd type with a public field but inaccessible, with a fixed memory area but not fixed.

Of course, there are simpler practices:

    unsafe struct S4    {        public Object obj;        public fixed byte buffer[4];    }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.