[Translated] C # 7 series, Part 9: ref structs ref structure

Original: https://blogs.msdn.microsoft.com/mazhou/2018/03/02/c-7-series-part-9-ref-structs/

background

In the previous article, I explained a lot of new C # features, each feature is to enhance problem-solving language or introduced. Specifically, I explained the value types and reference types, passing parameters by value, passing parameters by reference, ref ref local variables and return the result as well as in parameters. This is where many of the features are designed for high-performance scene.

and in ref parameters can help avoid copying values, thereby reducing the memory allocation. When you have local variables allocated in the stack as the actual parameter passing method, it is efficient to do so, in this case, are all allocated on the stack; does not require heap allocation.

For high performance and native development scenarios, you may want to "stack only" Always stay on the execution stack, and therefore the operation of this type of object can only occur on the stack, the scope open to any managed heap this type of external references should be banned.

ref structure

ref struct only a value on the stack type:

  • Performance of a sequence structure layout; (Annotation: can be understood as a continuous memory)
  • It can only be used on the stack. That it is used as a method parameters and local variables;
  • It can not be a static or a class or instance of normal structure member;
  • You can not be a method of asynchronous method or parameter lambda expressions;
  • Not dynamic binding, packing, unpacking, packaging or conversion.

ref struct is also known as an embedded reference.

Examples

The following code defines a structure ref.

public ref struct MyRefStruct
{
    public int MyIntValue1;
    public int MyIntValue2;

    [EditorBrowsable(EditorBrowsableState.Never)]
    public override bool Equals(object obj) => throw new NotSupportedException();

    [EditorBrowsable(EditorBrowsableState.Never)]
    public override int GetHashCode() => throw new NotSupportedException();

    [EditorBrowsable(EditorBrowsableState.Never)]
    public override string ToString() => throw new NotSupportedException();
}

Please note that I have covered inherited from System.Object Equals, GetHashCode and ToString methods. Because the ref structure does not allow boxing, so you will not be able to call these two (translation: the original two, three should be) based method.

You can use MyRefStruct in method parameters or local variables as the conventional value types, but you can not use it in other places.

 You can also create a read-only ref structure, simply add the readonly command structure to the ref statement can be.

public readonly ref struct MyRefStruct
{
    public readonly int MyIntValue1;
    public readonly int MyIntValue2;

    public MyRefStruct(int value1, int value2)
    {
        this.MyIntValue1 = value1;
        this.MyIntValue2 = value2;
    }

    [EditorBrowsable(EditorBrowsableState.Never)]
    public override bool Equals(object obj) => throw new NotSupportedException();

    [EditorBrowsable(EditorBrowsableState.Never)]
    public override int GetHashCode() => throw new NotSupportedException();

    [EditorBrowsable(EditorBrowsableState.Never)]
    public override string ToString() => throw new NotSupportedException();
}

As with the conventional read-only structure, all instances of the field / property needs to be set to read-only.

Metadata

ref structure may be used in C # 7.2. This feature requires compiler level change to work for backward compatibility with previous assembly generated by the compiler. The compiler will issue [Obsolete] and [IsByRefLike] characteristics ref structure declaration.

If any of the old assembly references the library contains ref structure type, [Obsolete] attribute will affect and prevent the code is compiled.

The following declaration is generated for the structure above ref IL.

.class public sequential ansi sealed beforefieldinit Demo.MyRefStruct
extends [System.Runtime]System.ValueType
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (
        01 00 00 00
    )
.custom instance void [System.Runtime]System.ObsoleteAttribute::.ctor(string, bool) = (
        01 00 52 54 79 70 65 73 20 77 69 74 68  20  65 6d
         62  65  64  64  65  64  20  72  65  66  65  72  65 6e 63  65 
        73  20  61  72  65  20 6e 6f 74  20  73  75  70  70 6f 72 
        74  65  64  20  69 6e 20  74  68  69  73  20  76  65  72  73 
        69 6f 6e 20 6f66 20 79 6f 75 72 20 63 6f 6d 70
        69 6c 65 72 2e 01 00 00
    )
.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (
        01 00 00 00
    )
// Fields
.field public initonly int32 MyIntValue1
.field public initonly int32 MyIntValue2
// Methods
.method public hidebysig specialname rtspecialname
instance void .ctor (
int32 value1,
int32 value2
        ) cil managed
    {
// Method begins at RVA 0x2090
// Code size 16 (0x10)
.maxstack 8
// (no C# code)
        IL_0000: nop
// this.MyIntValue1 = value1;
        IL_0001: ldarg.0
        IL_0002: ldarg.1
        IL_0003: stfld int32 Demo.MyRefStruct::MyIntValue1
// this.MyIntValue2 = value2;
        IL_0008: ldarg.0
        IL_0009: ldarg.2
        IL_000a: stfld int32 Demo.MyRefStruct::MyIntValue2
// (no C# code)
        IL_000f: ret
    } // end of method MyRefStruct::.ctor
.method public hidebysig virtual
instance bool Equals (
object obj
        ) cil managed
    {
// Method begins at RVA 0x20a1
// Code size 6 (0x6)
.maxstack 8
// throw new NotSupportedException();
        IL_0000: newobj instance void [System.Runtime]System.NotSupportedException::.ctor()
// (no C# code)
        IL_0005: throw
    } // end of method MyRefStruct::Equals
.method public hidebysig virtual
instance int32 GetHashCode () cil managed
    {
.custom instance void [System.Runtime]System.ComponentModel.EditorBrowsableAttribute::.ctor(valuetype [System.Runtime]System.ComponentModel.EditorBrowsableState) = (
            01 00 01 00 00 00 00 00
        )
// Method begins at RVA 0x20a8
// Code size 6 (0x6)
.maxstack 8
// throw new NotSupportedException();
        IL_0000: newobj instance void [System.Runtime]System.NotSupportedException::.ctor()
// (no C# code)
        IL_0005: throw
    } // end of method MyRefStruct::GetHashCode
.method public hidebysig virtual
instance string ToString () cil managed
    {
.custom instance void [System.Runtime]System.ComponentModel.EditorBrowsableAttribute::.ctor(valuetype [System.Runtime]System.ComponentModel.EditorBrowsableState) = (
            01 00 01 00 00 00 00 00
        )
// Method begins at RVA 0x20af
// Code size 6 (0x6)
.maxstack 8
// throw new NotSupportedException();
        IL_0000: newobj instance void [System.Runtime]System.NotSupportedException::.ctor()
// (no C# code)
        IL_0005: throw
    } // end of method MyRefStruct::ToString
} // end of class Demo.MyRefStruct

Span<T>和Memory<T>

With ref class type of support, and now all that can continuously provide uniform memory access type. The System. Of Span <T> represents a continuous memory space, can be used for the execution stack, heap managed and unmanaged common heap memory operation.

The following is ReadOnlySpan <T> is a simple use, for removing spaces beginning of the string.

internal class Program
{
    private static void Main(string[] args)
    {
        string text = "  I am using C# 7.2 Span<T>!";
        Console.WriteLine(TrimStart(text).ToArray());
    }

    private static ReadOnlySpan<char> TrimStart(ReadOnlySpan<char> text)
    {
        if (text.IsEmpty)
        {
            return text;
        }

        int i = 0;
        char c;

        while ((c = text[i]) == ' ')
        {
             i++;
        }

        return text.Slice(i);
    }
}

in conclusion

C # 7.2 language features added for high-performance scenarios, and provides a low level of efficiency and the development of native interoperability scenarios. R & lt EF structure also may stackalloc, Span <T>, fixed buffers and Ranges (C # 7.3) is used together with productivity.

Note: To use this feature, Visual Studio 2017 version 15.5 or later.

 

Series:

Guess you like

Origin www.cnblogs.com/wenhx/p/csharp-7-series-part-9-ref-structs.html