[译]C# 7系列,Part 9: ref structs ref结构
2021-01-22 15:14
标签:port 高版本 值传递 引入 return sig 成员 object 通用 原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/02/c-7-series-part-9-ref-structs/ 背景 在之前的文章中,我解释了许多新的C#特性,每一个特性都是为了增强语言或者解决问题而引入的。具体来说,我解释了值类型和引用类型、按值传递参数、按引用传递参数、ref局部变量和ref返回结果以及in参数。这其中许多功能是为高性能场景设计的。 ref和in参数可以帮助避免复制值,从而减少内存分配。当你有分配在堆栈的局部变量作为方法的实际参数传递时,这么做是有效率的的,在这种情况下,所有的分配都在堆栈上;不需要堆分配。 对于高性能和原生开发场景,你可能希望“仅限堆栈”类型始终停留在执行堆栈上,因此对这种类型的对象的操作只能发生在堆栈上,在作用域中公开给托管堆的任何对这种类型的外部引用都应该被禁止。 ref结构 ref struct是仅在堆栈上的值类型: ref struct也被称为嵌入式引用。 示例 下面的代码定义了一个ref结构。 请注意,我已经覆盖了从System.Object继承的Equals、GetHashCode和ToString方法。因为ref结构不允许装箱,所以你将无法调用这两个(译注:原文两个,应该是三个)基方法。 你可以在方法参数或局部变量中使用MyRefStruct作为常规值类型,但不能在其他地方使用它。
你也可以创建只读ref结构,只需将readonly指令添加到ref结构声明中即可。 与常规只读结构一样,需要将所有实例字段/属性设置为只读。 元数据 ref结构在C# 7.2中可用。此功能需要编译器级别更改才能工作,以便与以前编译器生成的程序集向后兼容。编译器会为ref结构声明发出[Obsolete]和[IsByRefLike]特性。 如果任何旧的程序集引用了包含ref结构类型的库,[Obsolete]属性将影响并阻止代码编译。 下面是为上面的ref结构声明生成的IL。 Span 有了类ref类型的支持,现在就可以为所有连续内存访问提供统一的类型。System.Span 下面是ReadOnlySpan 结论 C# 7.2为高性能场景添加了语言特性,并为低级别的原生开发和互操作性场景提供了效率。ref结构还可以与stackalloc、Span 注意:要使用这个特性,需要Visual Studio 2017 15.5或更高版本。 系列文章: [译]C# 7系列,Part 9: ref structs ref结构 标签:port 高版本 值传递 引入 return sig 成员 object 通用 原文地址:https://www.cnblogs.com/wenhx/p/csharp-7-series-part-9-ref-structs.html
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();
}
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();
}
.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 6f 66 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
internal class Program
{
private static void Main(string[] args)
{
string text = " I am using C# 7.2 Span
文章标题:[译]C# 7系列,Part 9: ref structs ref结构
文章链接:http://soscw.com/index.php/essay/45481.html